Конвертировать структурированный массив в обычный массив NumPy - PullRequest
37 голосов
/ 11 мая 2011

Я думаю, что ответ будет очень очевидным, но сейчас я его не вижу.

Как преобразовать массив записей обратно в обычный ndarray?

Предположим, у меня есть следующий простой структурированный массив:

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

, затем яхочу преобразовать его в:

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

Я пытался asarray и astype, но это не сработало.

ОБНОВЛЕНИЕ (решено: вместо этого float32 (f4)из float64 (f8))

ОК, я попробовал решение Роберта (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 ]

35 голосов
/ 16 апреля 2012

Самый простой метод, вероятно,

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

(float обычно заменяется типом элементов в x: x.dtype[0]). Это предполагает, что все элементы имеют одинаковый тип.

Этот метод дает вам обычную версию numpy.ndarray за один шаг (в отличие от двух шагов, требуемых методом view(…).reshape(…).

22 голосов
/ 11 мая 2011
[~]
|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.]])
7 голосов
/ 11 мая 2011
np.array(x.tolist())
array([[ 1.,  4.],
      [ 2., -1.]])

но, может быть, есть лучший метод ...

1 голос
/ 08 июня 2019

В сочетании с изменениями в том, как он обрабатывает многополевую индексацию, numpy предоставил две новые функции, которые могут помочь в преобразовании в / из структурированных массивов:

В numpy.lib.recfunctions это structured_to_unstructured и unstructured_to_structured. repack_fields - это еще одна новая функция.

Из 1.16 заметок о выпуске

многополевые представления возвращают представление вместо копии

Индексирование структурированного массива с несколькими полями, например, arr [['f1', 'f3']], возвращает представление в исходный массив вместо копии. Возвращенное представление часто будет иметь дополнительные байты заполнения, соответствующие промежуточным полям в исходном массиве, в отличие от ранее, что повлияет на код, такой как arr [['f1', 'f3']]. View ('float64'). Это изменение было запланировано начиная с 1.7. С тех пор операции, выполняющие этот путь, генерируют FutureWarnings. Дополнительные предупреждения на будущее об этом изменении были добавлены в 1.12.

Чтобы помочь пользователям обновить свой код для учета этих изменений, в модуль numpy.lib.recfunctions был добавлен ряд функций, которые позволяют безопасно выполнять такие операции. Например, приведенный выше код можно заменить на structd_to_unstructured (arr [['f1', 'f3']], dtype = 'float64'). См. Раздел «Доступ к нескольким полям» в руководстве пользователя.

...