54

我认为答案将非常明显,但我目前看不到。

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

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

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

然后我想将其转换为:

array([[ 1.,  4.],
       [ 2., -1.]])

我试过asarrayand astype,但是没有用。

更新(已解决: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')])

进而:

data_array = data.view(np.float).reshape(data.shape + (-1,))

给出:

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

这是一个具有其他数字和另一种形状的数组。我做错什么了?

4

5 回答 5

45

最简单的方法大概是

x.view((float, len(x.dtype.names)))

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

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

于 2012-04-16T09:05:07.987 回答
31
[~]
|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.]])
于 2011-05-10T23:16:33.133 回答
14
np.array(x.tolist())
array([[ 1.,  4.],
      [ 2., -1.]])

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

于 2011-05-10T23:01:01.737 回答
13

结合如何处理多字段索引的更改,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')。请参阅用户指南的“访问多个字段”部分。

于 2019-06-07T23:15:43.413 回答
0

使用root_numpy的函数rec2array的一个非常简单的解决方案:

np_array = rec2array(x)

root_numpy实际上已被弃用,但rec2array 代码仍然很有用(来源here):

def rec2array(rec, fields=None):

  simplify = False

  if fields is None:
      fields = rec.dtype.names
  elif isinstance(fields, string_types):
      fields = [fields]
      simplify = True

  # Creates a copy and casts all data to the same type
  arr = np.dstack([rec[field] for field in fields])

  # Check for array-type fields. If none, then remove outer dimension.
  # Only need to check first field since np.dstack will anyway raise an
  # exception if the shapes don't match
  # np.dstack will also fail if fields is an empty list
  if not rec.dtype[fields[0]].shape:
      arr = arr[0]

  if simplify:
      # remove last dimension (will be of size 1)
      arr = arr.reshape(arr.shape[:-1])

  return arr
于 2020-03-29T22:12:12.130 回答