#python #arrays #python-3.x #numpy #structured-array
#python #массивы #python-3.x #numpy #структурированный массив
Вопрос:
Допустим, у меня есть следующий массив:
arr = np.array([[1,2], [3,4]], dtype='u1')
и я хочу преобразовать его в структурированный массив, подобный этому:
strarr = np.array([(1,2), (3,4)], dtype=[('a', 'u1'), ('b', 'u1')])
Если я просто попробую
arr.astype([('a', 'u1'), ('b', 'u1')])
он возвращает
>>> array([[(1, 1), (2, 2)],
[(3, 3), (4, 4)]], dtype=[('a', 'u1'), ('b', 'u1')])
Как я могу преобразовать массив так, чтобы он использовал все элементы строки для заполнения полей (при условии, что числа совпадают) вместо дублирования каждого элемента?
Ответ №1:
Для этого существуют специальные вспомогательные функции:
>>> from numpy.lib.recfunctions import unstructured_to_structured
Итак,
>>> import numpy as np
>>> arr = np.array([[1,2], [3,4]], dtype='u1')
>>> unstructured_to_structured(arr, dtype=np.dtype([('a', 'u1'), ('b', 'u1')]))
array([(1, 2), (3, 4)], dtype=[('a', 'u1'), ('b', 'u1')])
Вы также можете создать представление:
>>> arr.ravel().view(dtype=np.dtype([('a', 'u1'), ('b', 'u1')]))
array([(1, 2), (3, 4)], dtype=[('a', 'u1'), ('b', 'u1')])
И в этом простом случае это нормально, но если вы решите использовать представление, вам иногда приходится беспокоиться о том, как упакован массив. Обратите внимание, представление не копирует базовый буфер! Что может сделать его намного более эффективным, если вы работаете с большими массивами.
Ответ №2:
Предполагается, что данные для структурированного массива представляют собой список кортежей:
In [5]: arr = np.array([[1,2], [3,4]], dtype='u1')
In [6]: alist = [tuple(i) for i in arr]
In [7]: alist
Out[7]: [(1, 2), (3, 4)]
In [9]: np.array(alist, dtype=[('a', 'u1'), ('b', 'u1')])
Out[9]: array([(1, 2), (3, 4)], dtype=[('a', 'u1'), ('b', 'u1')])
Обратите внимание, что входные данные отражают отображение выходных данных.
В этом случае также возможно представление (базовые данные не изменяются):
In [10]: arr.view(dtype=[('a', 'u1'), ('b', 'u1')])
Out[10]:
array([[(1, 2)],
[(3, 4)]], dtype=[('a', 'u1'), ('b', 'u1')])
In [11]: _.ravel() # but needs a shape correction
Out[11]: array([(1, 2), (3, 4)], dtype=[('a', 'u1'), ('b', 'u1')])