【问题标题】:How to convert numpy.recarray to numpy.array?如何将 numpy.recarray 转换为 numpy.array?
【发布时间】:2011-10-20 20:57:53
【问题描述】:

将 numpy 的 recarray 转换为普通数组的最佳方法是什么?

我可以先做一个.tolist(),然后再做一个array(),但这似乎有点低效..

例子:

import numpy as np
a = np.recarray((2,), dtype=[('x', int), ('y', float), ('z', int)])

>>> a
  rec.array([(30408891, 9.2944097561804909e-296, 30261980),
   (44512448, 4.5273310988985789e-300, 29979040)], 
  dtype=[('x', '<i4'), ('y', '<f8'), ('z', '<i4')])

>>> np.array(a.tolist())
   array([[  3.04088910e+007,   9.29440976e-296,   3.02619800e+007],
   [  4.45124480e+007,   4.52733110e-300,   2.99790400e+007]])

【问题讨论】:

  • 您没有得到任何答案,因为我们不理解您的问题。尝试改写您的问题,并包含任何相关代码。
  • 对于那些反对的选民,我要求你再耐心一点。这是一个以前没有在这里问过问题并且没有太多时间修改问题的人。如果问题在这种糟糕的形式中停留太久,请务必投反对票。
  • 好吧对不起,添加了一个例子。这更清楚了吗?

标签: python numpy


【解决方案1】:

我认为“普通数组”是指同质 dtype 的 NumPy 数组。给定一个recarray,如:

>>> a = np.array([(0, 1, 2),
              (3, 4, 5)],[('x', int), ('y', float), ('z', int)]).view(np.recarray)
rec.array([(0, 1.0, 2), (3, 4.0, 5)], 
      dtype=[('x', '<i4'), ('y', '<f8'), ('z', '<i4')])

我们必须首先使每一列具有相同的 dtype。然后我们可以通过相同的 dtype 查看数据将其转换为“普通数组”:

>>> a.astype([('x', '<f8'), ('y', '<f8'), ('z', '<f8')]).view('<f8')
array([ 0.,  1.,  2.,  3.,  4.,  5.])

astype 返回一个新的 numpy 数组。所以上面需要额外的内存,其数量与a 的大小成正比。 a的每一行需要4+8+4=16字节,而a.astype(...)需要8*3=24字节。调用view 不需要新的内存,因为view 只是改变了底层数据的解释方式。

a.tolist() 返回一个新的 Python 列表。每个 Python 数字都是一个对象,它比 numpy 数组中的等效表示需要更多的字节。所以a.tolist() 需要比a.astype(...) 更多的内存。

调用a.astype(...).view(...)也比np.array(a.tolist())快:

In [8]: a = np.array(zip(*[iter(xrange(300))]*3),[('x', int), ('y', float), ('z', int)]).view(np.recarray)

In [9]: %timeit a.astype([('x', '<f8'), ('y', '<f8'), ('z', '<f8')]).view('<f8')
10000 loops, best of 3: 165 us per loop

In [10]: %timeit np.array(a.tolist())
1000 loops, best of 3: 683 us per loop

【讨论】:

  • 您可能需要确保数组是连续的:np.ascontiguousarray(a, [('x', 'stackoverflow.com/questions/29629157/…
【解决方案2】:

这是一个使用pandas的相对干净的解决方案:

>>> import numpy as np
>>> import pandas as pd
>>> a = np.recarray((2,), dtype=[('x', int), ('y', float), ('z', int)])
>>> arr = pd.DataFrame(a).to_numpy()
>>> arr
array([[9.38925058e+013, 0.00000000e+000, 1.40380704e+014],
       [1.40380704e+014, 6.93572751e-310, 1.40380484e+014]])
>>> arr.shape
(2, 3)
>>> arr.dtype
dtype('float64')

首先将来自recarray 的数据加载到pd.DataFrame,然后使用DataFrame.to_numpy 方法导出数据。我们可以看到,这个方法调用已经自动将所有数据转换为float64类型。

【讨论】:

    猜你喜欢
    • 2017-08-24
    • 1970-01-01
    • 1970-01-01
    • 2021-08-30
    • 2021-06-01
    • 2021-03-10
    • 1970-01-01
    • 2018-12-30
    • 1970-01-01
    相关资源
    最近更新 更多