我有一个像这样的结构化数组:
a = np.array([(0. , 1. , 2.) , (10. , 11. , 12. )] ,
dtype=[('PositionX', '<f8'), ('PositionY', '<f8'), ('PositionZ', '<f8')])
现在,我想要添加记录0(a [0])和记录1(a [1]),以获得类似: (10.,12.,14。)
当我写下这样的东西时:
a[0] + a[1]
我收到错误,告诉我你不能添加两个dtype对象或类似的东西。
所以,我想也许我可以将[0]变为常规向量,然后执行添加。
但是numpy.array(a [0])与[0]具有相同的dtype,而numpy.array(a[0],dtype=np.float64)
也不起作用。
那么,谁能告诉我如何将[0]转换为常规向量?请不要告诉我将结构化数组转换为常规数组。因为我只想拿几个我的阵列记录并添加。 此外,我真的想知道如何将像[0]这样的对象转换为常规向量。
答案 0 :(得分:1)
你因为a [i]是元组而得到错误,你不能直接添加元组。你必须访问它们,更实际的方法是:
map(sum, zip(*a))
zip功能正是您正在寻找的,之后您必须根据需要处理每个条目,在您的情况sum
中,您也可以尝试:
result = []
for elem in zip(*a):
result.append(sum(elem))
答案 1 :(得分:0)
In [206]: a
Out[206]:
array([( 0., 1., 2.), ( 10., 11., 12.)],
dtype=[('PositionX', '<f8'), ('PositionY', '<f8'), ('PositionZ', '<f8')])
记录是复合numpy dtype对象,显示为元组。
In [207]: type(a[0])
Out[207]: numpy.void
In [208]: a[0].dtype
Out[208]: dtype([('PositionX', '<f8'), ('PositionY', '<f8'), ('PositionZ', '<f8')])
数组的字段(&#39;列&#39;)是数组,并执行正常的数组数学。
In [209]: a['PositionX']
Out[209]: array([ 0., 10.])
In [210]: a['PositionX']+a['PositionY']
Out[210]: array([ 1., 21.])
但是还没有为化合物dtype定义数学:
In [211]: a[0]+a[1]
TypeError: ufunc 'add' did not contain a loop with signature matching types dtype([('PositionX', '<f8'), ('PositionY', '<f8'), ('PositionZ', '<f8')]) ....
如果你允许我将整个数组转换为2d,我可以添加行:
In [213]: a1=np.array(a.tolist())
In [214]: a1
Out[214]:
array([[ 0., 1., 2.],
[ 10., 11., 12.]])
In [215]: a1[0]+a1[1]
Out[215]: array([ 10., 12., 14.])
还有其他方法可以将结构化数组转换为2d(使用view
或astype
)但这个tolist()
最容易使用且最一致。有关详情,请参阅https://stackoverflow.com/a/43380941/901925
但要使用单个记录进行数学处理,您必须将它们转换为数组或将其视为显示的元组。
In [218]: np.array(a[0].tolist())
Out[218]: array([ 0., 1., 2.])
In [219]: np.array(a[0].tolist())+np.array(a[1].tolist())
Out[219]: array([ 10., 12., 14.])
但是你对这个数组感到满意,还是想要回到a.dtype
?
In [234]: np.array(tuple(asum), a.dtype)
Out[234]:
array(( 10., 12., 14.),
dtype=[('PositionX', '<f8'), ('PositionY', '<f8'), ('PositionZ', '<f8')])
结构化数组的数据必须是元组或元组列表。
如果您使用dtype
显示的压缩方法,则必须执行相同的@Mohamed Lakhal
转换
In [236]: [i+j for i,j in zip(a[0],a[1])]
Out[236]: [10.0, 12.0, 14.0]
In [237]: np.array(tuple([i+j for i,j in zip(a[0],a[1])]), a.dtype)
虽然Divakar评论的view
方法会转换整个数组:
In [227]: a.view('<f8')
Out[227]: array([ 0., 1., 2., 10., 11., 12.])
In [228]: a.view('<f8').reshape(-1,3)
Out[228]:
array([[ 0., 1., 2.],
[ 10., 11., 12.]])
它不适用于记录:
In [229]: a[0].view('<f8')
....
ValueError: new type not compatible with array.
这是更好的二维数组转换器:
In [239]: a.view('3f8')
Out[239]:
array([[ 0., 1., 2.],
[ 10., 11., 12.]])
In [240]: a[0].view('3f8')
Out[240]: array([ 0., 1., 2.])
In [241]: a[[0,1]].view('3f8')
Out[241]:
array([[ 0., 1., 2.],
[ 10., 11., 12.]])
In [242]: a[[0,1]].view('3f8').sum(axis=0)
Out[242]: array([ 10., 12., 14.])