像point_type
這樣的結構化數組沒有定義涉及多個字段的數學運算。
隨着樣品從https://stackoverflow.com/a/33455682/901925
In [470]: point_type = [('x', float), ('y', float)]
In [471]: points = np.array([(1,2), (3,4), (5,6)], dtype=point_type)
In [472]: points
Out[472]:
array([(1.0, 2.0), (3.0, 4.0), (5.0, 6.0)],
dtype=[('x', '<f8'), ('y', '<f8')])
In [473]: points[0]+points[1]
...
TypeError: unsupported operand type(s) for +: 'numpy.void' and 'numpy.void'
相反,我可以創建一個二維數組,然後將其視爲point_type
- 設置DataBuffer佈局將是相同的:
In [479]: points = np.array([(1,2), (3,4), (5,6)],float)
In [480]: points
Out[480]:
array([[ 1., 2.],
[ 3., 4.],
[ 5., 6.]])
In [481]: points.view(point_type)
Out[481]:
array([[(1.0, 2.0)],
[(3.0, 4.0)],
[(5.0, 6.0)]],
dtype=[('x', '<f8'), ('y', '<f8')])
In [482]: points.view(point_type).view(np.recarray).x
Out[482]:
array([[ 1.],
[ 3.],
[ 5.]])
我可以做數學橫跨行,並繼續以點的形式查看結果:
In [483]: (points[0]+points[1]).view(point_type).view(np.recarray)
Out[483]:
rec.array([(4.0, 6.0)],
dtype=[('x', '<f8'), ('y', '<f8')])
In [484]: _.x
Out[484]: array([ 4.])
In [485]: points.sum(0).view(point_type)
Out[485]:
array([(9.0, 12.0)],
dtype=[('x', '<f8'), ('y', '<f8')])
我也可以與point_type
開始,並認爲它是2D的數學,然後視圖它回
pdt1=np.dtype((float, (2,)))
In [502]: points
Out[502]:
array([(1.0, 2.0), (3.0, 4.0), (5.0, 6.0)],
dtype=[('x', '<f8'), ('y', '<f8')])
In [503]: points.view(pdt1)
Out[503]:
array([[ 1., 2.],
[ 3., 4.],
[ 5., 6.]])
In [504]: points.view(pdt1).sum(0).view(point_type)
Out[504]:
array([(9.0, 12.0)],
dtype=[('x', '<f8'), ('y', '<f8')])
因此,有可能查看和在陣列上作爲2d和作爲recarray操作。要是漂亮或有用,它可能需要在用戶定義的類中進行埋設。
另一種選擇從recarray
類中挑選想法的選項。在它的核心,它只是一個結構化數組,其中包含專門的__getattribute__
(和setattribute)方法。該方法首先檢索正常的數組方法和屬性(例如x.shape
,x.sum
)。然後它會嘗試在定義的字段名中對attr
進行罰款。
def __getattribute__(self, attr):
try:
return object.__getattribute__(self, attr)
except AttributeError: # attr must be a fieldname
pass
fielddict = ndarray.__getattribute__(self, 'dtype').fields
try:
res = fielddict[attr][:2]
except (TypeError, KeyError):
raise AttributeError("record array has no attribute %s" % attr)
return self.getfield(*res)
...
points.view(np.recarray).x
變得points.getfield(*points.dtype.fields['x'])
。
一種替代方法將是從namedtuple
(/usr/lib/python3.4/collections/__init__.py
)借用,並定義x
和y
性質,這將索引2D陣列的[:,0]
和[:,1]
列。 將這些屬性添加到np.matrix
的子類可能是最容易的,讓該類確保大多數數學結果是2d。
'np.recarray'是結構化數組,允許您以字段的形式訪問字段 - 對命名的等價物進行排序。但是你不能輕易地在結構化數組上執行2D數學。 – hpaulj