如何改变numpy数组dtype和重塑



我有一个从HDF5文件中读取的数组,它是一个元组的1D数组。它的dtype是:

[('cycle', '<u2'), ('dxn', 'i1'), ('i (mA)', '<f4'), ('V', '<f4'), ('R(Ohm)', '<f4')] 

我想把它从一个n × 1的数组转换成一个(n/5) × 5的类型为np.float的数组。

我试过np。类型,但这不起作用——它只返回n个元素。有什么简单的方法吗?

dtypes的混合使得这种转换比通常更棘手。最后的答案是,将字段复制到目标数组兼具速度和通用性。

将结构化数组转换为常规NumPy数组-建议作为副本,但这种情况下所有字段都是float。

让我们构造一个示例:

In [850]: dt
Out[850]: dtype([('cycle', '<u2'), ('dxn', 'i1'), ('i (mA)', '<f4'), ('V', '<f4'), ('R(Ohm)', '<f4')])
In [851]: x=np.zeros((3,),dt)
In [852]: x['cycle']=[0,10,23]
In [853]: x['dxn']=[3,2,2]
In [854]: x['V']=[1,1,1]
In [855]: x
Out[855]: 
array([(0, 3, 0.0, 1.0, 0.0), (10, 2, 0.0, 1.0, 0.0),
       (23, 2, 0.0, 1.0, 0.0)], 
      dtype=[('cycle', '<u2'), ('dxn', 'i1'), ('i (mA)', '<f4'), ('V', '<f4'), ('R(Ohm)', '<f4')])

我们可以按照链接中建议的方式查看3个float字段:

In [856]: dt1=np.dtype([('f0','float32',(3))])
In [857]: y=x[list(x.dtype.names[2:])].view(dt1)
# or x[list(x.dtype.names[2:])].view((np.float32, 3))
In [858]: y
Out[858]: 
array([([0.0, 1.0, 0.0],), ([0.0, 1.0, 0.0],), ([0.0, 1.0, 0.0],)], 
      dtype=[('f0', '<f4', (3,))])
In [859]: y['f0']
Out[859]: 
array([[ 0.,  1.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  1.,  0.]], dtype=float32)

但是如果我想改变所有的值,我需要让y成为一个副本。不允许一次写入多个字段。

In [863]: y=x[list(x.dtype.names[2:])].view(dt1).copy()
In [864]: y['f0']=np.arange(9.).reshape(3,3)
只有一个dtype的

view不能捕获行结构;我们必须把它加回reshapedt1(3,)形状可以解决这个问题。

In [867]: x[list(x.dtype.names[2:])].view(np.float32)
Out[867]: array([ 0.,  1.,  0.,  0.,  1.,  0.,  0.,  1.,  0.], dtype=float32)

https://stackoverflow.com/a/5957455/901925建议浏览一个列表。

In [868]: x.tolist()
Out[868]: [(0, 3, 0.0, 1.0, 0.0), (10, 2, 0.0, 1.0, 0.0), (23, 2, 0.0, 1.0, 0.0)]
In [869]: np.array(x.tolist())
Out[869]: 
array([[  0.,   3.,   0.,   1.,   0.],
       [ 10.,   2.,   0.,   1.,   0.],
       [ 23.,   2.,   0.,   1.,   0.]])

单个字段可以用astype:

转换
In [878]: x['cycle'].astype(np.float32)
Out[878]: array([  0.,  10.,  23.], dtype=float32)
In [879]: x['dxn'].astype(np.float32)
Out[879]: array([ 3.,  2.,  2.], dtype=float32)

但不包含多个字段:

In [880]: x.astype(np.float32)
Out[880]: array([  0.,  10.,  23.], dtype=float32)

recfunctions帮助操作结构化数组

from numpy.lib import recfunctions

它们中的许多构造一个新的空结构,并逐个字段复制值。在这种情况下的等效:

In [890]: z=np.zeros((3,5),np.float32)    
In [891]: for i in range(5):
   .....:     z[:,i] = x[x.dtype.names[i]]
In [892]: z
Out[892]: 
array([[  0.,   3.,   0.,   1.,   0.],
       [ 10.,   2.,   0.,   1.,   0.],
       [ 23.,   2.,   0.,   1.,   0.]], dtype=float32)

在这种情况下,它比np.array(x.tolist())慢一点。但对于30000条记录,这要快得多。

通常在一个结构化数组中有比字段更多的记录,所以字段的迭代并不慢。

最新更新