将结构化数组转换为常规NumPy数组

jor*_*ris 37 python numpy recarray

我认为答案非常明显,但我现在还没有看到.

如何将记录数组转换回常规ndarray?

假设我有以下简单的结构化数组:

x = np.array([(1.0, 4.0,), (2.0, -1.0)], dtype=[('f0', '<f8'), ('f1', '<f8')])
Run Code Online (Sandbox Code Playgroud)

然后我想将其转换为:

array([[ 1.,  4.],
       [ 2., -1.]])
Run Code Online (Sandbox Code Playgroud)

我试过asarrayastype,但没有奏效.

UPDATE(求解:float32(f4)而不是float64(f8))

好的,我尝试了Robert(x.view(np.float64).reshape(x.shape + (-1,)) )的解决方案,并且使用简单的数组它可以完美地工作.但是对于我想要转换的数组,它给出了一个奇怪的结果:

data = np.array([ (0.014793682843446732, 0.006681123282760382, 0.0, 0.0, 0.0, 0.0008984912419691682, 0.0, 0.013475529849529266, 0.0, 0.0),
       (0.014793682843446732, 0.006681123282760382, 0.0, 0.0, 0.0, 0.0008984912419691682, 0.0, 0.013475529849529266, 0.0, 0.0),
       (0.014776384457945824, 0.006656022742390633, 0.0, 0.0, 0.0, 0.0008901208057068288, 0.0, 0.013350814580917358, 0.0, 0.0),
       (0.011928378604352474, 0.002819152781739831, 0.0, 0.0, 0.0, 0.0012627150863409042, 0.0, 0.018906937912106514, 0.0, 0.0),
       (0.011928378604352474, 0.002819152781739831, 0.0, 0.0, 0.0, 0.001259754877537489, 0.0, 0.01886274479329586, 0.0, 0.0),
       (0.011969991959631443, 0.0028706740122288465, 0.0, 0.0, 0.0, 0.0007433745195157826, 0.0, 0.011164642870426178, 0.0, 0.0)], 
      dtype=[('a_soil', '<f4'), ('b_soil', '<f4'), ('Ea_V', '<f4'), ('Kcc', '<f4'), ('Koc', '<f4'), ('Lmax', '<f4'), ('malfarquhar', '<f4'), ('MRN', '<f4'), ('TCc', '<f4'), ('Vcmax_3', '<f4')])
Run Code Online (Sandbox Code Playgroud)

然后:

data_array = data.view(np.float).reshape(data.shape + (-1,))
Run Code Online (Sandbox Code Playgroud)

得到:

In [8]: data_array
Out[8]: 
array([[  2.28080997e-20,   0.00000000e+00,   2.78023241e-27,
          6.24133580e-18,   0.00000000e+00],
       [  2.28080997e-20,   0.00000000e+00,   2.78023241e-27,
          6.24133580e-18,   0.00000000e+00],
       [  2.21114197e-20,   0.00000000e+00,   2.55866881e-27,
          5.79825816e-18,   0.00000000e+00],
       [  2.04776835e-23,   0.00000000e+00,   3.47457730e-26,
          9.32782857e-17,   0.00000000e+00],
       [  2.04776835e-23,   0.00000000e+00,   3.41189244e-26,
          9.20222417e-17,   0.00000000e+00],
       [  2.32706550e-23,   0.00000000e+00,   4.76375305e-28,
          1.24257748e-18,   0.00000000e+00]])
Run Code Online (Sandbox Code Playgroud)

这是一个包含其他数字和另一种形状的数组.我做错了什么?

Eri*_*got 35

最简单的方法可能是

x.view((float, len(x.dtype.names)))
Run Code Online (Sandbox Code Playgroud)

(float通常必须通过在元件的类型替换x:x.dtype[0]).这假设所有元素都具有相同的类型.

此方法numpy.ndarray在一个步骤中为您提供常规版本(与view(…).reshape(…)方法所需的两个步骤相反).

  • 我一直在使用这种方法一段时间了; 不幸的是现在我得到了"FutureWarning:Numpy已经检测到你可能正在通过选择结构化数组中的多个字段来查看或写入返回的数组.这个代码可能会破坏numpy 1.13,因为这将返回一个视图而不是一个副本 - - 有关详情,请参阅发行说明." 有什么想法如何处理? (4认同)
  • 这在 Numpy 1.14 中对我不起作用。假设我有以下结构化数组:`arr = np.array([(105.0, 34.0, 145.0, 217.0)], dtype=[('a', 'f4'), ('b', 'f4'), ('c', 'f4'), ('d', 'f4')])`。然后尝试通过 `out = arr[0].view((np.float32, len(arr.dtype.names)))` 将内部的 4 元组转换为常规数组会导致 `ValueError: Change the dtype of a仅当 itemsize 不变时才支持 0d 数组。 (3认同)

Rob*_*ern 24

[~]
|5> x = np.array([(1.0, 4.0,), (2.0, -1.0)], dtype=[('f0', '<f8'), ('f1', '<f8')])

[~]
|6> x.view(np.float64).reshape(x.shape + (-1,))
array([[ 1.,  4.],
       [ 2., -1.]])
Run Code Online (Sandbox Code Playgroud)


hpa*_*ulj 12

结合处理多字段索引方式的变化,numpy提供了两个新函数,可以帮助在结构化数组之间进行转换:

在 中numpy.lib.recfunctions,这些是structured_to_unstructuredunstructured_to_structuredrepack_fields是另一个新功能。

来自1.16发行说明

多字段视图返回视图而不是副本

索引具有多个字段的结构化数组,例如 arr[['f1', 'f3']],返回原始数组的视图而不是副本。与之前不同的是,返回的视图通常会有额外的填充字节对应于原始数组中的中间字段,这会影响 arr[['f1', 'f3']].view('float64') 等代码。从 numpy 1.7 开始就计划进行此更改。从那时起,这条路径上的操作就发出了 FutureWarnings。1.12 中添加了有关此更改的其他 FutureWarnings。

为了帮助用户更新他们的代码以应对这些变化,numpy.lib.recfunctions 模块中添加了许多功能,可以安全地允许此类操作。例如,上面的代码可以替换为structured_to_unstructured(arr[['f1', 'f3']], dtype='float64')。请参阅用户指南的“访问多个字段”部分。


And*_*nca 8

np.array(x.tolist())
array([[ 1.,  4.],
      [ 2., -1.]])
Run Code Online (Sandbox Code Playgroud)

但也许有更好的方法......

  • 这很慢,因为您首先将高效打包的NumPy数组转换为常规Python列表.官方方法要快得多(参见我的回答). (4认同)
  • 这确实很慢,但唯一可靠的答案。其他的对我不起作用(numpy 1.14.x)。 (3认同)
  • 当结构化数组有多种数据类型时,此方法有效,其他方法在此情况下失败。对于速度并不重要的单元测试非常有用,只需与工作进行比较即可。 (3认同)