将numpy结构化数组高效转换为2d数组

eufgjt7s  于 2023-10-19  发布在  其他
关注(0)|答案(3)|浏览(106)

我有一个结构化的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浮点数组。我该如何执行此操作?

rnmwe5a2

rnmwe5a21#

这里有一种方法,它至少应该是内存有效的,而且不会太慢:

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作为结果数组。

xxb16uws

xxb16uws2#

recfunctions有一些函数可以处理重数组(以及结构化数组)。它记录在结构化数组主页上。它需要特殊的装载:

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是这样工作的,尽管我还没有检查它的代码。
我还没有计算这些选择的时间。

fquxozlt

fquxozlt3#

特别地,可以用'names'/'formats'字典重建新的数据类型对象,其中'names'保存当前字段名称,'formats'-相应的dtype格式:

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]])

相关问题