Мои попытки создать структурированные массивы терпят неудачу:
Я создаю форму массива (4,5)
sample = np.array([[0.01627555, 1.55885081, 1.99043222, 0.00898849, 1.43987417],
[0.01875182, 0.97853587, 2.09924081, 0.00474326, 1.31002428],
[0.01905054, 1.74849054, 1.78033106, 0.01303594, 1.28518933],
[0.01753927, 1.22486495, 1.88287677, 0.01823483, 1.36472148]])
назначьте dtype для каждого из пяти столбцов:
sample.dtype = [('X', 'f4'), ('Y', 'f4'), ('Z', 'f4'), ('f', 'f4'), ('g', 'f4' )]
я бы ожидал:
sample['X']
> array([0.01627555, 0.01875182, 0.01905054, 0.01753927], dtype=float32)
Однако то, что я делаю, дает
array([[-1.6328180e-12, 1.9988040e+00],
[ 7.9082486e+13, 2.0124049e+00],
[ 7.7365790e-24, 1.9725413e+00],
[ 3.6306835e+36, 1.9853595e+00]], dtype=float32)
Я знаю, как это сделать в пандах и т. д., Но в этом случае мне нужен структурированный массив. Что я делаю не так?
Вам нужно переформатировать массив с помощью np.core.records.array в список кортежей, чтобы преобразовать его в recarray
dtype = [('X', 'f4'), ('Y', 'f4'), ('Z', 'f4'), ('f', 'f4'), ('g', 'f4' )]
arr = np.core.records.array(tuple(sample.T), dtype=dtype)
Выход:
>>> arr # note the recarray
rec.array([(0.01627555, 1.5588508, 1.9904323, 0.00898849, 1.4398742),
(0.01875182, 0.9785359, 2.0992408, 0.00474326, 1.3100243),
(0.01905054, 1.7484906, 1.780331 , 0.01303594, 1.2851893),
(0.01753927, 1.224865 , 1.8828768, 0.01823483, 1.3647215)],
dtype=[('X', '<f4'), ('Y', '<f4'), ('Z', '<f4'), ('f', '<f4'), ('g', '<f4')])
>>> arr['X'] # note you still have ndarray
array([0.01627555, 0.01875182, 0.01905054, 0.01753927], dtype=float32)
На главной structured array
странице документации представлены recfunctions
:
https://numpy.org/doc/stable/user/basics.rec.html#module-numpy.lib.recfunctions
In [2]: import numpy.lib.recfunctions as rf
Определите объект dtype
:
In [11]: dt = np.dtype([('X', 'f4'), ('Y', 'f4'), ('Z', 'f4'), ('f', 'f4'), ('g', 'f4' )])
rf
имеет функцию, предназначенную для выполнения такого преобразования:
In [13]: arr = rf.unstructured_to_structured(sample, dtype=dt)
In [14]: arr
Out[14]:
array([(0.01627555, 1.5588508, 1.9904323, 0.00898849, 1.4398742),
(0.01875182, 0.9785359, 2.0992408, 0.00474326, 1.3100243),
(0.01905054, 1.7484906, 1.780331 , 0.01303594, 1.2851893),
(0.01753927, 1.224865 , 1.8828768, 0.01823483, 1.3647215)],
dtype=[('X', '<f4'), ('Y', '<f4'), ('Z', '<f4'), ('f', '<f4'), ('g', '<f4')])
Вы также можете создать структурированный массив со списком кортежей, который будет очень похож на показанное выше отображение массива.
In [16]: np.array([tuple(x) for x in sample], dtype=dt)
В другом ответе используется функция records
для создания массива из списка массивов, по одному на поле:
np.core.records.fromarrays(list(sample.T), dtype=dt)
Как и многие функции rf
, эта функция создает «пустой» массив с нужным dtype и формой и копирует в него значения по имени поля:
In [31]: dt.names
Out[31]: ('X', 'Y', 'Z', 'f', 'g')
In [32]: res = np.zeros(4, dtype=dt)
In [33]: for i,name in enumerate(dt.names):
...: res[name] = sample[:,i]