[Numpy-discussion] Subclassing record array

Loïc BERTHE berthe.loic@gmail....
Sat Oct 17 10:13:57 CDT 2009


   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 ?


-- 
LB


More information about the NumPy-Discussion mailing list