如何将numpy.recarray转换为numpy.array?

2024-10-05 15:22:53 发布

您现在位置:Python中文网/ 问答频道 /正文

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

Tags: 方法importnumpy示例asnp数组float
1条回答
网友
1楼 · 发布于 2024-10-05 15:22:53

我认为“普通数组”是指一个同质数据类型的NumPy数组。重新排列,例如:

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

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

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

相关问题 更多 >