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-... :
[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 ?