[Numpy-discussion] numpy migration
Duncan Smith
buzzard at contactbox.co.uk
Tue Apr 24 21:26:57 EDT 2007
Timothy Hochberg wrote:
> On 4/23/07, Duncan Smith <buzzard at urubu.freeserve.co.uk> wrote:
>
>>
>> Hello,
>> Since moving to numpy I've had a few problems with my existing
>> code. It basically revolves around the numpy scalar types. e.g.
>>
>> ------------------------------------------------
>>
>> >>> import Numeric as N
>> >>> a = N.array([[0,1],[2,3]])
>> >>> a
>>
>> array([[0, 1],
>> [2, 3]])
>>
>> >>> i = a[0,0]
>> >>> 1/i
>>
>>
>> Traceback (most recent call last):
>> File "<pyshell#30>", line 1, in -toplevel-
>> 1/i
>> ZeroDivisionError: integer division or modulo by zero
>>
>> >>> b = a * 1.5
>> >>> b
>>
>> array([[ 0. , 1.5],
>> [ 3. , 4.5]])
>>
>> >>> N.floor(b)
>>
>> array([[ 0., 1.],
>> [ 3., 4.]])
>>
>> >>> ================================ RESTART
>>
>> ================================
>>
>> >>> import numpy as N
>> >>> a = N.array([[0,1],[2,3]])
>> >>> a
>>
>> array([[0, 1],
>> [2, 3]])
>>
>> >>> i = a[0,0]
>> >>> 1/i
>>
>> 0
>
>
>
> You should be getting a warning here. Did one disappear in the cut and
> paste? Or are you using a nonstandard shell that eats warnings? Or an old
> version of numpy?
>
Python 2.5.1 / numpy 1.0.1 / IDLE (under Windows 2000). No warning.
> In any event if you want an error rather than a warning for zero division,
> use:
>
>>>> 1/i
>
> Warning: divide by zero encountered in long_scalars
> 0
> SyntaxError: invalid syntax
>
>>>> N.seterr(divide='raise')
>
> {'over': 'print', 'divide': 'print', 'invalid': 'print', 'under': 'ignore'}
>
>>>> 1/i
>
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> FloatingPointError: divide by zero encountered in long_scalars
>
> Although I'm not sure why that's a floating point error.
>
True, bug or feature?, I'm really looking for a ZeroDivisionError.
[snip]
> ----------------------------------------------
>
>>
>> An additional problem involves classes that have e.g. __rmul__ methods
>> defined and are sufficiently similar to numpy arrays that my classes'
>> __rmul__ methods are not invoked when using numpy scalars.
>
>
>
>
> Try adding "__array_priority__ = 10" or somesuch to your classes. This
> should tell numpy to back off and let your methods go first when doing
> mixed
> operations. Searching for "__array_priority__" will probably turn up some
> examples.
>
Yes, it did. But for my classes it seems to have no effect. Below is a
fairly minimal example.
-----------------example.py--------------------
from __future__ import division
import numpy
class MyClass(object):
def __init__(self, arr, labels):
self.arr = arr
self.labels = labels
def __repr__(self):
return numpy.array2string(self.arr, separator=', ') +
repr(self.labels)
def __len__(self):
return len(self.labels)
def __getitem__(self, key):
return self.arr[key]
def __setitem__(self, key, item):
self.arr[key] = item
def __mul__(self, other):
return self.__class__(self.arr * other, self.labels)
__rmul__ = __mul__
----------------------------------------------------
>>> import example
>>> import numpy as N
>>> ex = example.MyClass(N.array([[6,7],[8,9]]), ['axis0', 'axis1'])
>>> i = ex.arr[0,0]
>>> ex
[[6, 7],
[8, 9]]['axis0', 'axis1']
>>> ex * i
[[36, 42],
[48, 54]]['axis0', 'axis1']
>>> i * ex
array([[36, 42],
[48, 54]])
>>>
It seems that it requires having __len__, __setitem__ and __getitem__
defined to get the undesired behaviour.
[snip]
>
> I think you should be able to do everything you need, by using seterr at
> startup to make numpy picky about division errors and then using array
> priority to make your methods have precedence over numpy's.
>
Thanks Tim. Unfortunately I really need it to raise a
ZeroDivisionError. Homing in on the second issue, but I'm not sure I
can easily do away with the __len__ method (and I definitely need the
others). Cheers.
Duncan
More information about the NumPy-Discussion
mailing list