[Numpy-discussion] Subclassing record array

Charles R Harris charlesr.harris at gmail.com
Sun Oct 18 00:22:31 EDT 2009


On Sat, Oct 17, 2009 at 9:13 AM, Loïc BERTHE <berthe.loic at 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.

Chuck
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20091017/adf49a0e/attachment.html>


More information about the NumPy-Discussion mailing list