Как сгладить структурированный массив NumPy, где каждый элемент сам по себе является NUMPY массивом (dtype = 'O') - PullRequest
0 голосов
/ 14 октября 2019

У меня есть структурированный массив NumPy, где каждый элемент массива сам по себе является NUMPY массивом (dtype = 'O'). Каждый массив элементов в одной и той же строке всегда имеет одинаковую длину, в то время как массивы элементов в разных строках могут иметь переменную длину. Например, это может выглядеть примерно так:

array([(array([1], dtype=int32),       array([0.1], dtype=float64)),
       (array([2, 3, 4], dtype=int32), array([0.2, 0.3, 0.4], dtype=float64)),
       (array([5, 6], dtype=int32),    array([0.5, 0.6], dtype=float64))],
      dtype=[('field_1', 'O'), ('field_2', 'O')])

Каков наилучший способ выравнивания такого массива таким образом, чтобы строки с длинами массива элементов = N были разложены в N строк? В идеале я хочу, чтобы плоский массив выглядел следующим образом:

array([(1, 0.1),
       (2, 0.2),
       (3, 0.3),
       (4, 0.4),
       (5, 0.5),
       (6, 0.6)],
      dtype=[('field_1', int32), ('field_2', float64)])

Но я также могу работать с другими форматами, если строки с длиной> 1 расширены, например:

array([(array([1], dtype=int32), array([0.1], dtype=float64)),
       (array([2], dtype=int32), array([0.2], dtype=float64)),
       (array([3], dtype=int32), array([0.3], dtype=float64)),
       (array([4], dtype=int32), array([0.4], dtype=float64)),
       (array([5], dtype=int32), array([0.5], dtype=float64)),
       (array([6], dtype=int32), array([0.6], dtype=float64))],
      dtype=[('field_1', 'O'), ('field_2', 'O')])

если это как-то проще реализовать.

Ответы [ 2 ]

1 голос
/ 15 октября 2019

аналогично приведенному выше, но с использованием списка и почтового индекса

z
array([(array([1]), array([0.1])),
       (array([2, 3, 4]), array([0.2, 0.3, 0.4])),
       (array([5, 6]), array([0.5, 0.6]))],
      dtype=[('field_1', 'O'), ('field_2', 'O')])

x = np.concatenate(z['field_1'])
y = np.concatenate(z['field_2'])

dt = np.dtype([('f0', '<i4'), ('f1', 'f8')])
np.asarray(list(zip(x, y)), dtype=dt)

array([(1, 0.1), (2, 0.2), (3, 0.3), (4, 0.4), (5, 0.5), (6, 0.6)],
      dtype=[('f0', '<i4'), ('f1', '<f8')])
0 голосов
/ 15 октября 2019

Я не уверен, что это «лучший» способ, но он выполняет то, что вы ищете. Я не знаю, как это можно было бы сделать полностью в памяти без копии, поэтому я бы начал с пустого массива.

>>>import numpy as np

>>>original = np.array([(np.array([1], dtype=np.int32), np.array([0.1], dtype=np.float64)),
...   (np.array([2], dtype=np.int32), np.array([0.2], dtype=np.float64)),
...   (np.array([3], dtype=np.int32), np.array([0.3], dtype=np.float64)),
...   (np.array([4], dtype=np.int32), np.array([0.4], dtype=np.float64)),
...   (np.array([5], dtype=np.int32), np.array([0.5], dtype=np.float64)),
...   (np.array([6], dtype=np.int32), np.array([0.6], dtype=np.float64))],
...   dtype=[('field_1', '<i4'), ('field_2', '<f8')])
>>>copy = np.empty((6,1), dtype=[('field_1', '<i4'), ('field_2', '<f8')])

Затем мы можем объединить 2 поля в исходном массиве

>>>copy['field_1'][:,0] = np.concatenate([original['field_1']])
>>>copy['field_2'][:,0] = np.concatenate([original['field_2']])
>>>copy
array([[(1, 0.1)],
   [(2, 0.2)],
   [(3, 0.3)],
   [(4, 0.4)],
   [(5, 0.5)],
   [(6, 0.6)]], dtype=[('field_1', '<i4'), ('field_2', '<f8')])

Последним шагом будет выравнивание копии

>>>copy.flatten()
array([(1, 0.1), (2, 0.2), (3, 0.3), (4, 0.4), (5, 0.5), (6, 0.6)],
  dtype=[('field_1', '<i4'), ('field_2', '<f8')])
...