Проблема здесь в том, что для создания структурированного массива вам нужен список кортежей. Это упоминается в Создание структурированного типа данных , где говорится, что среди других менее распространенных методов создания массивов входные данные должны быть списком кортежей, по одному кортежу на поле .
Итак, что вы можете сделать, это превратить ваш массив в список кортежей (здесь будет удобно zip
) и построить из него структурированный массив, используя np.fromiter
и указав dt
как dtype
:
np.fromiter(zip(*arr.T), dtype=dt)
array([(0, 20, 3.), (1, 21, 2.), (2, 23, 8.), (3, 26, 5.), (4, 31, 9.)],
dtype=[('index', '<i4'), ('timestamp', '<i4'), ('volume', '<f4')])
Другой (менее известный) подход, упомянутый @hpaulj в комментариях, использует np.lib.recfunctions.unstructured_to_structured
, который можно использовать для прямого построения структурированного массива from arr
и объект dtype с:
np.lib.recfunctions.unstructured_to_structured(a, dt)
array([(0, 20, 3.), (1, 21, 2.), (2, 23, 8.), ..., (2, 23, 8.),
(3, 26, 5.), (4, 31, 9.)],
dtype=[('index', '<i4'), ('timestamp', '<i4'), ('volume', '<f4')])
Или на основе этого другого сообщения есть также возможность создать массив записей , подкласс ndarray , очень похожий на структурированный массив с точки зрения использования, который поставляется с несколькими связанными вспомогательными функциями, такими как np.core.records.fromarrays
, которые можно использовать для создания массива простым способом:
np.core.records.fromarrays(arr.T,
names='index, timestamp, volume',
formats = '<i4, <i4, <f4')
rec.array([(0, 20, 3.), (1, 21, 2.), (2, 23, 8.), (3, 26, 5.),
(4, 31, 9.)],
dtype=[('index', '<i4'), ('timestamp', '<i4'), ('volume', '<f4')])
О r, чтобы создать его из объекта np.dtype
:
names, dtypes = list(zip(*dt.descr))
np.core.records.fromarrays(arr.transpose(),
names= ', '.join(names),
formats = ', '.join(dtypes))
Сроки, сравнивающие упомянутые методы, и некоторые другие возможные подходы:
a = np.concatenate([arr]*1000, axis=0)
%%timeit
np.core.records.fromarrays(a.T,
names='index, timestamp, volume',
formats = '<i4, <i4, <f4')
# 57.9 µs ± 1.18 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit np.lib.recfunctions.unstructured_to_structured(a, dt)
# 79.6 µs ± 1.32 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit np.fromiter(zip(*a.T), dtype=dt)
#2.1 ms ± 69.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit np.fromiter(map(tuple, a), dtype=dt)
#6.34 ms ± 65.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit np.array(list(zip(*a.T)), dtype=dt)
# 2.17 ms ± 107 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)