假设我有一个具有各种数字数据类型的 NumPy 结构化数组。作为一个基本的例子,
my_data = np.array( [(17, 182.1), (19, 175.6)], dtype='i2,f4')
如何将其转换为常规的 NumPy 浮点数组?
从这个答案,我知道我可以使用
np.array(my_data.tolist())
但显然它很慢,因为您“将有效打包的 NumPy 数组转换为常规 Python 列表”。
假设我有一个具有各种数字数据类型的 NumPy 结构化数组。作为一个基本的例子,
my_data = np.array( [(17, 182.1), (19, 175.6)], dtype='i2,f4')
如何将其转换为常规的 NumPy 浮点数组?
从这个答案,我知道我可以使用
np.array(my_data.tolist())
但显然它很慢,因为您“将有效打包的 NumPy 数组转换为常规 Python 列表”。
您可以使用 Pandas 轻松完成:
>>> import pandas as pd
>>> pd.DataFrame(my_data).values
array([[ 17. , 182.1000061],
[ 19. , 175.6000061]], dtype=float32)
The obvious way works:
>>> my_data
array([(17, 182.10000610351562), (19, 175.60000610351562)],
dtype=[('f0', '<i2'), ('f1', '<f4')])
>>> n = len(my_data.dtype.names) # n == 2
>>> my_data.astype(','.join(['f4']*n))
array([(17.0, 182.10000610351562), (19.0, 175.60000610351562)],
dtype=[('f0', '<f4'), ('f1', '<f4')])
>>> my_data.astype(','.join(['f4']*n)).view('f4')
array([ 17. , 182.1000061, 19. , 175.6000061], dtype=float32)
>>> my_data.astype(','.join(['f4']*n)).view('f4').reshape(-1, n)
array([[ 17. , 182.1000061],
[ 19. , 175.6000061]], dtype=float32)
这是一种方法(假设my_data
是一维结构化数组):
In [26]: my_data
Out[26]:
array([(17, 182.10000610351562), (19, 175.60000610351562)],
dtype=[('f0', '<i2'), ('f1', '<f4')])
In [27]: np.column_stack(my_data[name] for name in my_data.dtype.names)
Out[27]:
array([[ 17. , 182.1000061],
[ 19. , 175.6000061]], dtype=float32)
沃伦答案的变体(按字段复制数据):
x = np.empty((my_data.shape[0],len(my_data.dtype)),dtype='f4')
for i,n in enumerate(my_data.dtype.names):
x[:,i]=my_data[n]
或者你可以逐行迭代。 r
是一个元组。它必须转换为列表才能填充一行x
。如果行多,字段少,这会变慢。
for i,r in enumerate(my_data):
x[i,:]=list(r)
尝试一下可能很有启发性,但x.data=r.data
会出现错误:AttributeError: not enough data for array
. x
data 是一个有 4 个浮点数的缓冲区。 my_data
是一个包含 2 个元组的缓冲区,每个元组包含一个 int 和一个 float(或 [int float int float] 的序列)。 my_data.itemsize==6
. 一种或另一种方式,my_data
必须将其转换为所有浮点数,并删除元组分组。
但使用astype
Jaime 显示确实有效:
x.data=my_data.astype('f4,f4').data
在使用包含 5 个字段的 1000 项数组的快速测试中,逐个字段复制与使用astype
.