提问人:Ars ML 提问时间:9/6/2023 更新时间:9/6/2023 访问量:66
有效地将 numpy 结构化数组转换为 2d 数组
Convert numpy structured array to 2d array efficiently
问:
我有像这样大的结构化numpy数组:
array([(-0.85694593, -6.3997216, -1.5486323 , 37, 50, 0, 0),
(-1.1892447 , -11.417209 , -0.21771915, 97, 50, 0, 0),
(-0.84541476, -11.3712845, -0.8726147 , 75, 50, 0, 0), ...,
(-0.057407 , -6.266104 , 1.6693828 , 19, 0, 16, 63),
( 0.56391037, -11.262503 , 0.31594068, 0, 0, 150, 63),
( 0.9118347 , -11.4296665, -0.3372402 , 96, 0, 0, 0)],
dtype=[('x', '<f4'), ('y', '<f4'), ('z', '<f4'), ('intensity', 'u1'), ('timestamp', 'u1'), ('m', 'u1'), ('_', 'u1')])
请注意,第 0 到 2 列是浮点数,第 3 到 6 列是整数。
我想有效地将这个数组转换为浮点数的 2D 数组。我该如何执行此操作?
答:
2赞
juanpa.arrivillaga
9/6/2023
#1
这里有一种方法,至少应该是内存效率高的,而且速度不会太慢:
result = np.empty((arr.shape[0], len(arr.dtype.fields)), np.float32)
for i, field in enumerate(arr.dtype.fields):
result[:, i] = arr[field]
我假设你想要你的结果数组。np.float32
评论
0赞
hpaulj
9/6/2023
是的,大多数人使用这种按字段复制的方法。该分包还有一个功能,numpy.org/devdocs/user/...recfunctions
structured_to_unstructured
0赞
RomanPerekhrest
9/6/2023
#2
特别是,可以使用字典重建新的数据类型对象,其中保存当前字段名称和 - 相应的 dtype 格式:'names'/'formats'
'names'
'formats'
arr = np.array(arr.astype(np.dtype({'names': arr.dtype.names,
'formats':['<f4']*len(arr.dtype.names)})).tolist())
array([[-8.56945932e-01, -6.39972162e+00, -1.54863226e+00,
3.70000000e+01, 5.00000000e+01, 0.00000000e+00,
0.00000000e+00],
[-1.18924475e+00, -1.14172087e+01, -2.17719153e-01,
9.70000000e+01, 5.00000000e+01, 0.00000000e+00,
0.00000000e+00],
[-8.45414758e-01, -1.13712845e+01, -8.72614682e-01,
7.50000000e+01, 5.00000000e+01, 0.00000000e+00,
0.00000000e+00],
[-5.74069992e-02, -6.26610422e+00, 1.66938281e+00,
1.90000000e+01, 0.00000000e+00, 1.60000000e+01,
6.30000000e+01],
[ 5.63910365e-01, -1.12625027e+01, 3.15940678e-01,
0.00000000e+00, 0.00000000e+00, 1.50000000e+02,
6.30000000e+01],
[ 9.11834717e-01, -1.14296665e+01, -3.37240189e-01,
9.60000000e+01, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00]])
2赞
hpaulj
9/6/2023
#3
recfunctions
具有与 recarrays(以及扩展为结构化数组)一起使用的功能。它记录在主结构化数组页面上。它需要特殊负载:
In [204]: import numpy.lib.recfunctions as rf
In [205]: arr = np.array([(-0.85694593, -6.3997216, -1.5486323 , 37, 50, 0, 0),
...: (-1.1892447 , -11.417209 , -0.21771915, 97, 50, 0, 0),
...: (-0.84541476, -11.3712845, -0.8726147 , 75, 50, 0, 0),
...: (-0.057407 , -6.266104 , 1.6693828 , 19, 0, 16, 63),
...: ( 0.56391037, -11.262503 , 0.31594068, 0, 0, 150, 63),
...: ( 0.9118347 , -11.4296665, -0.3372402 , 96, 0, 0, 0)],
...: dtype=[('x', '<f4'), ('y', '<f4'), ('z', '<f4'), ('intensity', 'u1'), ('timestamp', 'u1'), ('m', 'u1'), ('_', 'u1')])
In [206]: arr
Out[206]:
array([(-0.85694593, -6.3997216, -1.5486323 , 37, 50, 0, 0),
(-1.1892447 , -11.417209 , -0.21771915, 97, 50, 0, 0),
...
( 0.9118347 , -11.4296665, -0.3372402 , 96, 0, 0, 0)],
dtype=[('x', '<f4'), ('y', '<f4'), ('z', '<f4'), ('intensity', 'u1'), ('timestamp', 'u1'), ('m', 'u1'), ('_', 'u1')])
该库中最近添加的一对转换器函数:
In [207]: arr1 = rf.structured_to_unstructured(arr)
In [208]: arr1
Out[208]:
array([[-8.56945932e-01, -6.39972162e+00, -1.54863226e+00,
3.70000000e+01, 5.00000000e+01, 0.00000000e+00,
0.00000000e+00],
[-1.18924475e+00, -1.14172087e+01, -2.17719153e-01,
9.70000000e+01, 5.00000000e+01, 0.00000000e+00,
0.00000000e+00],
...
[ 9.11834717e-01, -1.14296665e+01, -3.37240189e-01,
9.60000000e+01, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00]], dtype=float32)
另一个答案中的方法有效,因为对于结构化数组,结果是元组列表,它可以像列表列表一样容易地解析。但是,如果要创建结构化数组,则需要元组列表。 开发人员选择显示/解析结构化数组作为元组。tolist
np.array
numpy
records
In [209]: arr2 = np.array(arr.tolist()
In [211]: arr.tolist()
Out[211]:
[(-0.8569459319114685, -6.399721622467041, -1.548632264137268, 37, 50, 0, 0),
(-1.1892447471618652, -11.417208671569824, -0.2177191525697708, 97, 50, 0, 0),
...
(0.911834716796875, -11.429666519165039, -0.33724018931388855, 96, 0, 0, 0)]
许多工作是通过创建目标数组并逐个字段复制数据来实现的。由于通常记录数远大于字段数,因此效率相对较高。我假设这样做,尽管我没有检查过它的代码。recfunctions
structured_to_unstructured
我还没有确定这些替代方案的时间。
评论
arr.view((float, len(arr.dtype.names)))
ValueError: Changing the dtype to a subarray type is only supported if the total itemsize is unchanged