Подтвердить что ты не робот

Как преобразовать numpy.recarray в numpy.array?

Какой лучший способ преобразовать 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]])
4b9b3361

Ответ 1

Под "нормальным массивом", я так понимаю, вы имеете в виду массив NumPy однородного типа dtype. Учитывая повторение, например:

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