我们假设我有一个结构化数组如下:
import numpy as np
fields = [('f1', np.float32), ('f2', np.float32)]
k = np.ones(2, fields)
我希望能够访问多个字段并同时修改它们。我知道我可以使用视图访问多个字段。但我想要做的更像是以下内容,我将所有字段都修改为:
k[0] = k[0] * 2
但我收到此错误消息:
TypeError: unsupported operand type(s) for *: 'numpy.void' and 'int'
有没有人知道什么可行?越简单越好 - 我需要一些相当大的结构化数组来执行这些操作。我能想到的最好的想法是使用字段名称中的列表解析来组合k [0],将其转换为元组,并将其分配回来,但可能会有更优雅的解决方案:
k[0] = tuple([k[0][name] * 2 for name in k.dtype.names])
答案 0 :(得分:0)
使用这样的dtype
,有两种直接访问和修改数据的方法。按字段名称,例如k['f0']
,或元组形式的元素(行)。您正在使用第二种方法。如果字段数不是那么大,并且您需要访问许多元素,那么第一个更好。
但如果字段都具有相同的数据类型,则可以在等效的2d数组上进行数学运算。
In [937]: k = np.ones(5,fields)
In [938]: k2 = np.empty((5,2),dtype=np.float32)
In [939]: k2.data = k.data # share the data buffers
In [940]: k2 *= 2 # do math on the 2d view
In [942]: k2[0] += 3
In [943]: k # and see the effect via the shared buffer
Out[943]:
array([(5.0, 5.0), (2.0, 2.0), (2.0, 2.0), (2.0, 2.0), (2.0, 2.0)],
dtype=[('f1', '<f4'), ('f2', '<f4')])
view
同样适用
In [948]: k1 = k.view(np.float32).reshape(5,2)
In [951]: k1[1] = [3,4]
In [954]: k
Out[954]:
array([(5.0, 5.0), (3.0, 4.0), (2.0, 2.0), (2.0, 2.0), (2.0, 2.0)],
dtype=[('f1', '<f4'), ('f2', '<f4')])
但是使用混合dtypes,你可能必须坚持使用元组理解。
如果k
有混合类型:
In [1025]: k
Out[1025]:
array([(1.0, 1.0, b'1'), (1.0, 1.0, b'1')],
dtype=[('f1', '<f4'), ('f2', '<f4'), ('f3', 'S3')])
我可以使用名单列表查看浮点字段:
In [1027]: k[['f1','f2']][1]
Out[1027]: (1.0, 1.0)
但尝试使用元组修改这些字段不会做任何事情(尽管没有错误)。
In [1028]: k[['f1','f2']][1]=(2.0, 2.0)
看起来我必须一次设置一个字段,或者通过元组设置所有一个元素。
如果您需要做很多数学运算,请不要将数组分解为命名字段。