[Numpy-discussion] python user defined type

Christopher Barker Chris.Barker@noaa....
Thu Jul 10 15:43:18 CDT 2008


Nicolas Rougier wrote:
> I would like to create numpy array with my own (python) datatype, so I
> tried the obvious solution:
> 
> from numpy import *
> class Unit(object):
>     def __init__(self,value=0.0):
>         self.value = value
>     def __float__(self):
>         return self.value
>     def __repr__(self):
>         return str(self.value)

> a = array (array([[1,2],[3,4]]), dtype=Unit)

the dtype argument is designed to take a numpy type object, not an 
arbitrary class -- what you want in this case is dtype=numpy.object, 
which is what you did before. I'm a surprised this didn't raise an 
error, but it looks like you got an object array, but you objects you 
gave it are python integers.  All python classes are "objects" as far an 
numpy is concerned. The numpy dtypes are a description of a given number 
of bytes in memory -- python classes are stored as a pointer to the 
python object.

(and you really don't want to use "import *")

> Also, the commented line (a[0,0] = 0) makes the item to become an int
> while I need to set the value of the item instead, is that possible ?

a[0,0] = Unit(0)

You're setting the [0,0]th element to an object, you need to give it the 
object you want, the literal "0" is a python integer with the value zero.

numpy arrays of python objects act a whole lot like other python 
containers. What would you expect from :

a = [1,2,3,4]

a list of integers, no?

or

a = [Unit(1), Unit(2)]

#  a list of Units..

then

# a[0] = 3

now a list with the integer3 in the zeroth position, and a Unit in the 1st.

You did it right the first time:

a = array([[Unit(1), Unit(2)], [Unit(3), Unit(4)]])

though you need to be careful building object arrays of nested lists -- 
numpy won't unnecessarily figure out how do d-nest it. You might want to do:

 >>> import numpy as np
 >>> a = np.empty((2,2), np.object)
 >>> a
array([[None, None],
        [None, None]], dtype=object)
 >>> a[:,:] = [[Unit(1), Unit(2)], [Unit(3), Unit(4)]]
 >>> a
array([[1, 2],
        [3, 4]], dtype=object)

One more note:

class Unit(object):
     def __init__(self,value=0.0):
         self.value = value
     def __float__(self):
         return self.value
     def __repr__(self):
         return str(self.value)


__repr__ really should be something like:
     def __repr__(self):
         return "Unit(%g)%self.value"

eval(repr(Object)) == Object, ideally, plus it'll be easier to debug if 
you can see what it is.

-Chris



-- 
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R            (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception

Chris.Barker@noaa.gov


More information about the Numpy-discussion mailing list