我已经创建了一个numpy.recarray的子类。该类的目的是为记录数组提供漂亮的打印,同时保持记录数组的功能。
以下是代码:
import numpy as np
import re
class TableView(np.recarray):
def __new__(cls,array):
return np.asarray(array).view(cls)
def __str__(self):
return self.__unicode__().encode("UTF-8")
def __repr__(self):
return self.__unicode__().encode("UTF-8")
def __unicode__(self):
options = np.get_printoptions()
nrows = len(self)
print "unicode called"
if nrows > 2*options['edgeitems']:
if nrows > options['threshold']:
nrows = 2*options['edgeitems'] + 1
ncols = len(self.dtype)
fields = self.dtype.names
strdata = np.empty((nrows + 1,ncols),dtype='S32')
strdata[0] = fields
np_len = np.vectorize(lambda x: len(x))
maxcolchars = np.empty(ncols,dtype='i4')
for i, field in enumerate(fields):
strdata[1:,i] = re.sub('[\[\]]','',np.array_str(self[field])).split()
maxcolchars[i] = np.amax(np_len(strdata[:,i]))
rowformat = ' '.join(["{:>%s}" % maxchars for maxchars in maxcolchars])
formatrow = lambda row: (rowformat).format(*row)
strdata = np.apply_along_axis(formatrow,1,strdata)
return '\n'.join(strdata)
以下是它的打印方式:
In [3]: x = np.array([(22, 2, -1000000000.0, 2000.0), (22, 2, 400.0, 2000.0),
...: (22, 2, 500.0, 2000.0), (44, 2, 800.0, 4000.0), (55, 5, 900.0, 5000.0),
...: (55, 5, 1000.0, 5000.0), (55, 5, 8900.0, 5000.0),
...: (55, 5, 11400.0, 5000.0), (33, 3, 14500.0, 3000.0),
...: (33, 3, 40550.0, 3000.0), (33, 3, 40990.0, 3000.0),
...: (33, 3, 44400.01213545, 3000.0)],
...: dtype=[('subcase', '<i4'), ('id', '<i4'), ('vonmises', '<f4'), ('maxprincipal', '<f4')])
In [6]: TableView(x)
unicode called
Out[6]:
subcase id vonmises maxprincipal
22 2 -1.00000000e+09 2000.
22 2 4.00000000e+02 2000.
22 2 5.00000000e+02 2000.
44 2 8.00000000e+02 4000.
55 5 9.00000000e+02 5000.
55 5 1.00000000e+03 5000.
55 5 8.90000000e+03 5000.
55 5 1.14000000e+04 5000.
33 3 1.45000000e+04 3000.
33 3 4.05500000e+04 3000.
33 3 4.09900000e+04 3000.
33 3 4.44000117e+04 3000.
但是当我只打印一行时,这不起作用:
In [7]: TableView(x)[0]
Out[7]: (22, 2, -1000000000.0, 2000.0)
适用于多行:
In [8]: TableView(x)[0:1]
unicode called
Out[8]:
subcase id vonmises maxprincipal
22 2 -1.00000000e+09 2000.
经过进一步调查:
In [10]: type(TableView(x)[0])
Out[10]: numpy.record
In [11]: type(TableView(x)[0:1])
Out[11]: __main__.TableView
如何让TableView的numpy.record具有相同的 unicode ?
答案 0 :(得分:1)
你的诊断是对的。此类的单个元素是record
,而不是Tableview
数组。
使用切片或列表([0:1]
或[[0]]
进行索引是最直接的解决方案。
尝试继承np.record
并更改Tableview
的元素似乎很复杂。
您可以尝试自定义__getitem__
方法。索引数组时会调用此方法。
结束于:
else:
# return a single element
return obj
修改后的版本可能会返回单个元素Tableview
return Tableview([obj])
但这可能会产生某种无休止的递归,使您无法像常规记录那样访问元素。
否则您可能只想使用切片索引。