[Numpy-discussion] Subclassing record array
Darren Dale
dsdale24@gmail....
Sun Oct 18 07:06:52 CDT 2009
On Sun, Oct 18, 2009 at 12:22 AM, Charles R Harris
<charlesr.harris@gmail.com> wrote:
>
>
> On Sat, Oct 17, 2009 at 9:13 AM, Loïc BERTHE <berthe.loic@gmail.com> wrote:
>>
>> Hi,
>>
>> I would like to create my own class of record array to deal with units.
>>
>> Here is the code I used, inspired from
>>
>> http://docs.scipy.org/doc/numpy-1.3.x/user/basics.subclassing.html#slightly-more-realistic-example-attribute-added-to-existing-array
>> :
>>
>>
>> [code]
>> from numpy import *
>>
>> class BlocArray(rec.ndarray):
>> """ Recarray with units and pretty print """
>>
>> fmt_dict = {'S' : '%10s', 'f' : '%10.6G', 'i': '%10d'}
>>
>> def __new__(cls, data, titles=None, units=None):
>>
>> # guess format for each column
>> data2 = []
>> for line in zip(*data) :
>> try : data2.append(cast[int](line)) # integers
>> except ValueError :
>> try : data2.append(cast[float](line)) # reals
>> except ValueError :
>> data2.append(cast[str](line)) # characters
>>
>> # create the array
>> dt = dtype(zip(titres, [line.dtype for line in data2]))
>> obj = rec.array(data2, dtype=dt).view(cls)
>>
>> # add custom attributes
>> obj.units = units or []
>> obj._fmt = " ".join(obj.fmt_dict[d[1][1]] for d in dt.descr) + '\n'
>> obj._head = "%10s "*len(dt.names) % dt.names +'\n'
>> obj._head += "%10s "*len(dt.names) % tuple('(%s)' % u for u in
>> units) +'\n'
>>
>> # Finally, we must return the newly created object:
>> return obj
>>
>> titles = ['Name', 'Nb', 'Price']
>> units = ['/', '/', 'Eur']
>> data = [['fish', '1', '12.25'], ['egg', '6', '0.85'], ['TV', 1, '125']]
>> bloc = BlocArray(data, titles=titles, units=units)
>>
>> In [544]: bloc
>> Out[544]:
>> Name Nb Price
>> (/) (/) (Eur)
>> fish 1 12.25
>> egg 6 0.85
>> TV 1 125
>> [/code]
>>
>> It's almost working, but I have some isues :
>>
>> - I can't access data through indexing
>> In [563]: bloc['Price']
>> /home/loic/Python/numpy/test.py in <genexpr>((r,))
>> 50
>> 51 def __repr__(self):
>> ---> 52 return self._head + ''.join(self._fmt % tuple(r) for r in
>> self)
>>
>> TypeError: 'numpy.float64' object is not iterable
>>
>> So I think that overloading the __repr__ method is not that easy
>>
>> - I can't access data through attributes now :
>> In [564]: bloc.Nb
>> AttributeError: 'BlocArray' object has no attribute 'Nb'
>>
>> - I can't use 'T' as field in theses array as the T method is
>> already here as a shortcut for transpose
>>
>>
>> Have you any hints to make this work ?
>>
>>
>
> On adding units in general, you might want to contact Darren Dale who has
> been working in that direction also and has added some infrastructure in svn
> to make it easier. He also gave a short presentation at scipy2009 on that
> problem, which has been worked on before. No sense in reinventing the wheel
> here.
The units package I have been working on is called quantities. It is
available at the python package index, and the project is hosted at
launchpad as python-quantities. If quantities isn't a good fit, please
let me know why. At least the code can provide some example of how to
subclass ndarray.
Darren
More information about the NumPy-Discussion
mailing list