Структурированные массивы
Введение
Структурированные массивы — это ndarrays, тип данных которых представляет собой комбинацию более простых типов данных, организованных как последовательность именованных полей. Например,
>>> x = np.array([('Rex', 9, 81.0), ('Fido', 3, 27.0)],
... dtype=[('name', 'U10'), ('age', 'i4'), ('weight', 'f4')])
>>> x
array([('Rex', 9, 81.), ('Fido', 3, 27.)],
dtype=[('name', 'U10'), ('age', '<i4'), ('weight', '<f4')])
Здесь x — одномерный массив длиной два, тип данных которого представляет собой структуру с тремя полями: 1. строка длиной 10 символов или меньше, имя «имя», 2. 32-битное целое число, имя «возраст», и 3. 32-битное число с плавающей точкой, имя «вес».
Если вы индексируете x в позиции 1, вы получите структуру:
>>> x[1]
('Fido', 3, 27.0)
Вы можете получить доступ к отдельным полям структурированного массива и изменить их, индексируя по имени поля:
>>> x['age']
array([9, 3], dtype=int32)
>>> x['age'] = 5
>>> x
array([('Rex', 5, 81.), ('Fido', 5, 27.)],
dtype=[('name', 'U10'), ('age', '<i4'), ('weight', '<f4')])
Структурированные типы данных предназначены для имитации «структур» языка C и имеют аналогичную структуру памяти. Они предназначены для взаимодействия с кодом C и для низкоуровневой обработки структурированных буферов, например, для интерпретации двоичных блоков. Для этих целей они поддерживают специализированные функции, такие как подмассивы, вложенные типы данных и объединения, и позволяют контролировать структуру памяти структуры.
Пользователи, желающие обрабатывать табличные данные, такие как данные в файлах csv, могут найти более подходящие проекты pydata, такие как xarray, pandas или DataArray. Они предоставляют высокоуровневый интерфейс для анализа табличных данных и лучше оптимизированы для этого использования. Например, структура памяти, похожая на C-структуру, структурированных массивов в numpy, может привести к плохой работе кэша по сравнению с другими.
Структурированные типы данных
Структурированный тип данных можно рассматривать как последовательность байтов определенной длины (размер элемента структуры itemsize), которая интерпретируется как набор полей. Каждое поле имеет имя, тип данных и смещение в байтах внутри структуры. Тип данных поля может быть любым типом данных numpy, включая другие структурированные типы данных, а также может быть типом данных подмассива, который ведет себя как ndarray заданной формы. Смещения полей произвольны, и поля могут даже перекрываться. Эти смещения обычно определяются автоматически numpy, но также могут быть заданы.
Создание структурированных типов данных
Структурированные типы данных можно создавать с помощью функции numpy.dtype. Существует 4 альтернативных формы спецификации, которые различаются по гибкости и лаконичности. Более подробная информация приведена в справочной странице по Объектам типа данных, и в кратком виде они следующие:
-
Список кортежей, по одному кортежу на поле
Каждый кортеж имеет вид
(fieldname, datatype, shape), где форма необязательна.fieldname— это строка (или кортеж, если используются заголовки, см. Заголовки полей ниже),datatypeможет быть любым объектом, преобразуемым в тип данных, иshape— это кортеж целых чисел, определяющий форму подмассива.>>> np.dtype([('x', 'f4'), ('y', np.float32), ('z', 'f4', (2, 2))]) dtype([('x', '<f4'), ('y', '<f4'), ('z', '<f4', (2, 2))])Если
fieldname— это пустая строка'', полю будет присвоено имя по умолчанию видаf#, где#— целочисленный индекс поля, считая с 0 слева:>>> np.dtype([('x', 'f4'), ('', 'i4'), ('z', 'i8')]) dtype([('x', '<f4'), ('f1', '<i4'), ('z', '<i8')])Смещения байтов полей внутри структуры и общий размер элемента структуры определяются автоматически.
-
Строка со спецификациями типов данных, разделенных запятыми
В этой сокращенной записи могут использоваться любые из строковых спецификаций типов данных, разделенные запятыми. Размер элемента и смещения байтов полей определяются автоматически, а имена полей получают имена по умолчанию
f0,f1, и т.д.>>> np.dtype('i8, f4, S3') dtype([('f0', '<i8'), ('f1', '<f4'), ('f2', 'S3')]) >>> np.dtype('3int8, float32, (2, 3)float64') dtype([('f0', 'i1', (3,)), ('f1', '<f4'), ('f2', '<f8', (2, 3))]) -
Словарь массивов параметров поля
Это наиболее гибкая форма спецификации, так как она позволяет контролировать смещения байтов полей и размер элемента структуры.
Словарь содержит два обязательных ключа, «имена» и «форматы», и четыре необязательных ключа, «смещения», «размер_элемента», «выровненные» и «заголовки». Значения для «имен» и «форматов» должны соответственно быть списком имён полей и списком спецификаций типов данных, имеющих одинаковую длину. Необязательное значение «смещения» должно быть списком целочисленных смещений в байтах, по одному для каждого поля в структуре. Если «смещения» не указаны, смещения определяются автоматически. Необязательное значение «размер_элемента» должно быть целым числом, описывающим общий размер в байтах типа данных, который должен быть достаточно большим, чтобы содержать все поля.
>>> np.dtype({'names': ['col1', 'col2'], 'formats': ['i4', 'f4']}) dtype([('col1', '<i4'), ('col2', '<f4')]) >>> np.dtype({'names': ['col1', 'col2'], ... 'formats': ['i4', 'f4'], ... 'offsets': [0, 4], ... 'itemsize': 12}) dtype({'names':['col1','col2'], 'formats':['<i4','<f4'], 'offsets':[0,4], 'itemsize':12})Смещения могут быть выбраны таким образом, чтобы поля перекрывались, хотя это означает, что присваивание одному полю может перезаписать данные любого перекрывающегося поля. В качестве исключения, поля типа
numpy.object_не могут перекрываться с другими полями из-за риска перезаписи указателя внутреннего объекта, а затем его обращение к нему.Необязательное значение «выровненные» может быть установлено в
True, чтобы автоматическое вычисление смещений использовало выровненные смещения (см. Автоматические байтовые смещения и выравнивание), как будто параметр «выравнивание» вnumpy.dtypeбыл установлен в True.Необязательное значение «заголовки» должно быть списком заголовков той же длины, что и «имена», см. Заголовки полей ниже.
-
Словарь имён полей
Использование этой формы спецификации не рекомендуется, но она описана здесь, так как более старые коды numpy могут ее использовать. Ключами словаря являются имена полей, а значениями являются кортежи, определяющие тип и смещение:
>>> np.dtype({'col1': ('i1', 0), 'col2': ('f4', 1)}) dtype([('col1', 'i1'), ('col2', '<f4')])Эта форма не рекомендуется, так как словари Python не сохраняют порядок в версиях Python до Python 3.6, а порядок полей в структурированном типе данных имеет значение. Заголовки полей могут быть указаны, используя 3-кортеж, см. ниже.
Обработка и отображение структурированных типов данных
Список имён полей структурированного типа данных можно найти в атрибуте names объекта типа данных:
>>> d = np.dtype([('x', 'i8'), ('y', 'f4')])
>>> d.names
('x', 'y')
Имена полей могут быть изменены, присвоив атрибуту names последовательность строк той же длины.
Объект типа данных также имеет атрибут, похожий на словарь, fields, ключи которого — имена полей (и заголовки полей, см. ниже), а значения — кортежи, содержащие тип данных и смещение в байтах каждого поля.
>>> d.fields
mappingproxy({'x': (dtype('int64'), 0), 'y': (dtype('float32'), 8)})
И атрибут names, и атрибут fields будут равны None для неструктурированных массивов. Рекомендуемый способ проверить, является ли тип данных структурированным, — это использовать if dt.names is not None вместо if dt.names, чтобы учесть типы данных с 0 полями.
Строковое представление структурированного типа данных показано в форме «список кортежей», если это возможно, в противном случае numpy возвращается к использованию более общей формы словаря.
Автоматические байтовые смещения и выравнивание
Numpy использует один из двух методов для автоматического определения смещений байтов поля и общего размера элемента структурированного типа данных, в зависимости от того, был ли задан параметр align=True в качестве ключевого аргумента к numpy.dtype.
По умолчанию (align=False), numpy будет упаковывать поля таким образом, чтобы каждое поле начиналось со смещения в байтах, где закончилось предыдущее поле, и поля будут смежными в памяти.
>>> def print_offsets(d):
... print("offsets:", [d.fields[name][1] for name in d.names])
... print("itemsize:", d.itemsize)
>>> print_offsets(np.dtype('u1, u1, i4, u1, i8, u2'))
offsets: [0, 1, 2, 6, 7, 15]
itemsize: 17
Если align=True задано, numpy будет дополнять структуру так же, как многие компиляторы C дополняют C-структуру. Выровненные структуры могут улучшить производительность в некоторых случаях за счёт увеличения размера типа данных. Дополнительные байты вставляются между полями так, чтобы смещение байтов каждого поля было кратно выравниванию этого поля, которое обычно равно размеру поля в байтах для простых типов данных, см. PyArray_Descr.alignment. К структуре также будет добавлен дополнительный байт-заполнитель, таким образом, чтобы её размер элемента был кратен наибольшему выравниванию поля.
>>> print_offsets(np.dtype('u1, u1, i4, u1, i8, u2', align=True))
offsets: [0, 1, 4, 8, 16, 24]
itemsize: 32
Обратите внимание, что хотя почти все современные компиляторы C дополняют таким образом по умолчанию, дополнение в C-структурах зависит от реализации компилятора C, поэтому такая структура памяти не гарантируется, что будет точно соответствовать структуре соответствующей программы на языке C. Необходимо выполнить определённую работу, либо со стороны numpy, либо со стороны C, чтобы получить точное соответствие.
Если смещения полей и размер элемента структурированного массива удовлетворяют условиям выравнивания, массив будет иметь атрибут ALIGNED flag установленным.
Удобная функция numpy.lib.recfunctions.repack_fields преобразует выровненный тип данных или массив в упакованный и наоборот. Она принимает в качестве аргумента либо тип данных, либо структурированный ndarray, и возвращает копию с переупакованными полями, с или без дополнительных байтов.
Заголовки полей
В дополнение к именам полей, поля также могут иметь связанный заголовок, альтернативное имя, которое иногда используется в качестве дополнительного описания или псевдонима для поля. Заголовок можно использовать для индексирования массива так же, как и имя поля.
Чтобы добавить заголовки при использовании формы спецификации типа данных «список кортежей», имя поля может быть указано как кортеж из двух строк вместо одной строки, которая будет заголовком поля и именем поля соответственно. Например:
>>> np.dtype([(('my title', 'name'), 'f4')])
dtype([(('my title', 'name'), '<f4')])
При использовании первого формата спецификации на основе словаря, заголовки могут быть предоставлены в качестве дополнительного ключа 'titles' как описано выше. При использовании второго (не рекомендуется) формата спецификации на основе словаря заголовок можно указать, предоставив кортеж из 3 элементов (datatype, offset, title) вместо обычного кортежа из 2 элементов:
>>> np.dtype({'name': ('i4', 0, 'my title')})
dtype([(('my title', 'name'), '<i4')])
Словарь dtype.fields будет содержать заголовки в качестве ключей, если они используются. Это означает, что поле с заголовком будет представлено дважды в словаре полей. Значения кортежа для этих полей также будут содержать третий элемент — заголовок поля. Из-за этого, и потому что атрибут names сохраняет порядок полей, в то время как атрибут fields может этого не делать, рекомендуется перебирать поля dtype, используя атрибут names dtype, который не будет перечислять заголовки, как в примере:
>>> for name in d.names:
... print(d.fields[name][:2])
(dtype('int64'), 0)
(dtype('float32'), 8)
Типы объединения
Структурированные типы данных в numpy реализованы по умолчанию с базовым типом numpy.void, но можно интерпретировать другие типы numpy как структурированные типы, используя формат спецификации dtype (base_dtype, dtype) , описанный в Объекты типов данных. Здесь base_dtype — желаемый базовый тип dtype, а поля и флаги будут скопированы из dtype. Этот тип данных аналогичен типу «объединение» в C.
Индексирование и присваивание структурированным массивам
Присваивание данных структурированному массиву
Существует несколько способов присвоения значений структурированному массиву: использование кортежей Python, использование скалярных значений или использование других структурированных массивов.
Присвоение из типов Python (кортежей)
Самый простой способ присвоить значения структурированному массиву — использовать кортежи Python. Каждое присваиваемое значение должно быть кортежем длиной, равной количеству полей в массиве, а не списком или массивом, так как это вызовет правила векторизации numpy. Элементы кортежа присваиваются последовательно полям массива слева направо:
>>> x = np.array([(1, 2, 3), (4, 5, 6)], dtype='i8, f4, f8')
>>> x[1] = (7, 8, 9)
>>> x
array([(1, 2., 3.), (7, 8., 9.)],
dtype=[('f0', '<i8'), ('f1', '<f4'), ('f2', '<f8')])
Присвоение из скаляров
Скаляр, присвоенный структурированному элементу, будет присвоен всем полям. Это происходит, когда скаляр присваивается структурированному массиву или когда неструктурированный массив присваивается структурированному массиву:
>>> x = np.zeros(2, dtype='i8, f4, ?, S1')
>>> x[:] = 3
>>> x
array([(3, 3., True, b'3'), (3, 3., True, b'3')],
dtype=[('f0', '<i8'), ('f1', '<f4'), ('f2', '?'), ('f3', 'S1')])
>>> x[:] = np.arange(2)
>>> x
array([(0, 0., False, b'0'), (1, 1., True, b'1')],
dtype=[('f0', '<i8'), ('f1', '<f4'), ('f2', '?'), ('f3', 'S1')])
Структурированные массивы также могут быть присвоены неструктурированным массивам, но только если структурированный тип данных содержит только одно поле:
>>> twofield = np.zeros(2, dtype=[('A', 'i4'), ('B', 'i4')])
>>> onefield = np.zeros(2, dtype=[('A', 'i4')])
>>> nostruct = np.zeros(2, dtype='i4')
>>> nostruct[:] = twofield
Traceback (most recent call last):
...
TypeError: Cannot cast array data from dtype([('A', '<i4'), ('B', '<i4')]) to dtype('int32') according to the rule 'unsafe'
Присвоение из других структурированных массивов
Присваивание между двумя структурированными массивами происходит так, как если бы исходные элементы были преобразованы в кортежи и затем присвоены целевым элементам. То есть первое поле исходного массива присваивается первому полю целевого массива, второе поле аналогично и так далее, независимо от имен полей. Структурированные массивы с разным количеством полей не могут быть присвоены друг другу. Байты целевой структуры, которые не включены ни в одно из полей, не затрагиваются.
>>> a = np.zeros(3, dtype=[('a', 'i8'), ('b', 'f4'), ('c', 'S3')])
>>> b = np.ones(3, dtype=[('x', 'f4'), ('y', 'S3'), ('z', 'O')])
>>> b[:] = a
>>> b
array([(0., b'0.0', b''), (0., b'0.0', b''), (0., b'0.0', b'')],
dtype=[('x', '<f4'), ('y', 'S3'), ('z', 'O')])
Присвоение, включающее подмассивы
При присвоении полям, являющимся подмассивами, присваиваемое значение сначала будет векторизовано до формы подмассива.
Индексирование структурированных массивов
Доступ к отдельным полям
К отдельным полям структурированного массива можно получить доступ и изменить, индексируя массив именем поля.
>>> x = np.array([(1, 2), (3, 4)], dtype=[('foo', 'i8'), ('bar', 'f4')])
>>> x['foo']
array([1, 3])
>>> x['foo'] = 10
>>> x
array([(10, 2.), (10, 4.)],
dtype=[('foo', '<i8'), ('bar', '<f4')])
Полученный массив является представлением исходного массива. Он использует те же расположения памяти, и запись в представление изменяет исходный массив.
>>> y = x['bar']
>>> y[:] = 11
>>> x
array([(10, 11.), (10, 11.)],
dtype=[('foo', '<i8'), ('bar', '<f4')])
Это представление имеет тот же тип данных и размер элемента, что и индексированное поле, поэтому обычно это неструктурированный массив, за исключением случая вложенных структур.
>>> y.dtype, y.shape, y.strides
(dtype('float32'), (2,), (12,))
Если доступное поле является подмассивом, размеры подмассива добавляются к форме результата:
>>> x = np.zeros((2, 2), dtype=[('a', np.int32), ('b', np.float64, (3, 3))])
>>> x['a'].shape
(2, 2)
>>> x['b'].shape
(2, 2, 3, 3)
Доступ к нескольким полям
Можно индексировать и присваивать структурированному массиву с многопольным индексом, где индекс — это список имен полей.
Предупреждение
Поведение многопольных индексов изменилось с Numpy 1.15 на Numpy 1.16.
Результат индексирования многопольным индексом — представление исходного массива, как показано ниже:
>>> a = np.zeros(3, dtype=[('a', 'i4'), ('b', 'i4'), ('c', 'f4')])
>>> a[['a', 'c']]
array([(0, 0.), (0, 0.), (0, 0.)],
dtype={'names':['a','c'], 'formats':['<i4','<f4'], 'offsets':[0,8], 'itemsize':12})
Присваивание представлению изменяет исходный массив. Поля представления будут в том порядке, в котором они были индексированы. Обратите внимание, что в отличие от однопольного индексирования, тип данных представления имеет такой же размер элемента, как и исходный массив, и имеет поля в тех же смещениях, что и в исходном массиве, и отсутствующие поля просто отсутствуют.
Предупреждение
В Numpy 1.15 индексирование массива многопольным индексом возвращало копию результата выше, но с полями, упакованными в памяти, как если бы они были переданы через numpy.lib.recfunctions.repack_fields.
Новое поведение начиная с Numpy 1.16 приводит к дополнительным «заполняющим» байтам в расположении неиндексированных полей по сравнению с 1.15. Вам нужно будет обновить любой код, зависящий от данных с «упакованной» структурой. Например, код такой как:
>>> a[['a', 'c']].view('i8') # Fails in Numpy 1.16
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: When changing to a smaller dtype, its size must be a divisor of the size of original dtype
нужно будет изменить. Этот код вызывал ошибку FutureWarning с Numpy 1.12, и аналогичный код вызывал ошибку FutureWarning с версии 1.7.
В 1.16 в модуле numpy.lib.recfunctions были введены несколько функций, чтобы помочь пользователям учесть это изменение. Это numpy.lib.recfunctions.repack_fields. numpy.lib.recfunctions.structured_to_unstructured, numpy.lib.recfunctions.unstructured_to_structured, numpy.lib.recfunctions.apply_along_fields, numpy.lib.recfunctions.assign_fields_by_name и numpy.lib.recfunctions.require_fields.
Функция numpy.lib.recfunctions.repack_fields всегда может быть использована для воспроизведения старого поведения, так как она вернет упакованную копию структурированного массива. Например, код выше можно заменить на:
>>> from numpy.lib.recfunctions import repack_fields
>>> repack_fields(a[['a', 'c']]).view('i8') # supported in 1.16
array([0, 0, 0])
Кроме того, numpy теперь предоставляет новую функцию numpy.lib.recfunctions.structured_to_unstructured, которая является более безопасной и эффективной альтернативой для пользователей, которые хотят преобразовать структурированные массивы в неструктурированные массивы, так как представление выше часто предназначено для этого. Эта функция позволяет безопасно преобразовывать в неструктурированный тип, учитывая заполнение, часто избегает копирования, а также преобразует типы данных по мере необходимости, в отличие от представления.
>>> b = np.zeros(3, dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')])
>>> b[['x', 'z']].view('f4')
array([0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)
Код такой как:
>>> from numpy.lib.recfunctions import structured_to_unstructured >>> structured_to_unstructured(b[['x', 'z']]) array([0, 0, 0])
Присваивание массиву с многопольным индексом изменяет исходный массив:
>>> a[['a', 'c']] = (2, 3)
>>> a
array([(2, 0, 3.), (2, 0, 3.), (2, 0, 3.)],
dtype=[('a', '<i4'), ('b', '<i4'), ('c', '<f4')])
Это подчиняется правилам присваивания структурированных массивов, описанным выше. Например, это означает, что можно поменять значения двух полей с помощью соответствующих многопольных индексов:
>>> a[['a', 'c']] = a[['c', 'a']]
Индексирование целым числом для получения структурированного скаляра
Индексирование одного элемента структурированного массива (с целым индексом) возвращает структурированный скаляр:
>>> x = np.array([(1, 2., 3.)], dtype='i, f, f') >>> scalar = x[0] >>> scalar (1, 2., 3.) >>> type(scalar) <class 'numpy.void'>
В отличие от других скаляров numpy, структурированные скаляры изменяемы и действуют как представления в исходный массив, так что изменение скаляра изменит исходный массив. Структурированные скаляры также поддерживают доступ и присваивание по имени поля:
>>> x = np.array([(1, 2), (3, 4)], dtype=[('foo', 'i8'), ('bar', 'f4')])
>>> s = x[0]
>>> s['bar'] = 100
>>> x
array([(1, 100.), (3, 4.)],
dtype=[('foo', '<i8'), ('bar', '<f4')])
Аналогично кортежам, структурированные скаляры также могут быть индексированы целым числом:
>>> scalar = np.array([(1, 2., 3.)], dtype='i, f, f')[0] >>> scalar[0] 1 >>> scalar[1] = 4
Таким образом, кортежи можно рассматривать как эквивалент структурированных типов numpy в Python, так же как обычные целые числа Python являются эквивалентом целочисленных типов numpy. Структурированные скаляры могут быть преобразованы в кортеж, вызвав numpy.ndarray.item:
>>> scalar.item(), type(scalar.item()) ((1, 4.0, 3.0), <class 'tuple'>)
Просмотр структурированных массивов, содержащих объекты
Чтобы избежать перезаписи указателей на объекты в полях типа object, numpy в настоящее время не позволяет представлений структурированных массивов, содержащих объекты.
Сравнение структур
Если типы данных двух структурированных массивов void равны, проверка равенства массивов даст булевый массив с размерностями исходных массивов, с элементами, установленными в True , где все поля соответствующих структур равны. Структурированные типы данных равны, если имена полей, типы данных и заголовки одинаковы, игнорируя порядок байтов, и поля находятся в том же порядке:
>>> a = np.zeros(2, dtype=[('a', 'i4'), ('b', 'i4')])
>>> b = np.ones(2, dtype=[('a', 'i4'), ('b', 'i4')])
>>> a == b
array([False, False])
В настоящее время, если типы данных двух структурированных массивов void не эквивалентны, сравнение терпит неудачу, возвращая скалярное значение False. Это поведение устарело с версии numpy 1.10 и в будущем будет вызывать ошибку или выполнять поэлементное сравнение.
Операторы < и > всегда возвращают False при сравнении структурированных массивов void, и арифметические и побитовые операции не поддерживаются.
Массивы записей
В качестве необязательного удобства numpy предоставляет подкласс ndarray, numpy.recarray, который позволяет обращаться к полям структурированных массивов по атрибуту вместо только по индексу. Массивы записей используют специальный тип данных, numpy.record, который позволяет получить доступ к полям по атрибуту для структурированных скаляров, полученных из массива. Модуль numpy.rec предоставляет функции для создания recarray из различных объектов. Дополнительные вспомогательные функции для создания и обработки структурированных массивов можно найти в numpy.lib.recfunctions.
Самый простой способ создать массив записей — с помощью numpy.rec.array:
>>> recordarr = np.rec.array([(1, 2., 'Hello'), (2, 3., "World")],
... dtype=[('foo', 'i4'),('bar', 'f4'), ('baz', 'S10')])
>>> recordarr.bar
array([ 2., 3.], dtype=float32)
>>> recordarr[1:2]
rec.array([(2, 3., b'World')],
dtype=[('foo', '<i4'), ('bar', '<f4'), ('baz', 'S10')])
>>> recordarr[1:2].foo
array([2], dtype=int32)
>>> recordarr.foo[1:2]
array([2], dtype=int32)
>>> recordarr[1].baz
b'World'
numpy.rec.array может преобразовать множество аргументов в массивы записей, включая структурированные массивы:
>>> arr = np.array([(1, 2., 'Hello'), (2, 3., "World")],
... dtype=[('foo', 'i4'), ('bar', 'f4'), ('baz', 'S10')])
>>> recordarr = np.rec.array(arr)
Модуль numpy.rec предоставляет ряд других удобных функций для создания массивов записей, см. функции для создания массивов записей.
Представление структурированного массива в виде массива записей можно получить с помощью соответствующего представления:
>>> arr = np.array([(1, 2., 'Hello'), (2, 3., "World")],
... dtype=[('foo', 'i4'),('bar', 'f4'), ('baz', 'a10')])
>>> recordarr = arr.view(dtype=np.dtype((np.record, arr.dtype)),
... type=np.recarray)
Для удобства, представление ndarray как типа numpy.recarray автоматически преобразуется в тип numpy.record, поэтому тип данных можно опустить при представлении:
>>> recordarr = arr.view(np.recarray)
>>> recordarr.dtype
dtype((numpy.record, [('foo', '<i4'), ('bar', '<f4'), ('baz', 'S10')]))
Для возврата к обычному ndarray необходимо сбросить и тип данных, и тип. Следующее представление выполняет это, учитывая необычный случай, когда recordarr не является структурированным типом:
>>> arr2 = recordarr.view(recordarr.dtype.fields or recordarr.dtype, np.ndarray)
Поля массива записей, доступные по индексу или по атрибуту, возвращаются как массив записей, если поле имеет структурированный тип, но в противном случае как обычный ndarray.
>>> recordarr = np.rec.array([('Hello', (1, 2)), ("World", (3, 4))],
... dtype=[('foo', 'S6'),('bar', [('A', int), ('B', int)])])
>>> type(recordarr.foo)
<class 'numpy.ndarray'>
>>> type(recordarr.bar)
<class 'numpy.recarray'>
Обратите внимание, что если поле имеет такое же имя, как атрибут ndarray, то атрибут ndarray имеет приоритет. Такие поля недоступны по атрибуту, но остаются доступными по индексу.
Вспомогательные функции recarray
Коллекция утилит для работы со структурированными массивами.
Большинство этих функций изначально реализованы John Hunter для matplotlib. Они были переписаны и расширены для удобства.
- numpy.lib.recfunctions.append_fields(base, names, data, dtypes=None, fill_value=- 1, usemask=True, asrecarray=False)[source]
-
Добавление новых полей в существующий массив.
Имена полей задаются аргументом
names, соответствующие значения — аргументомdata. Если добавляется одно поле,names,dataиdtypesне должны быть списками, а только значениями.- Parameters
-
- basearray
-
Входной массив для расширения.
- namesстрока, последовательность
-
Строка или последовательность строк, соответствующие именам новых полей.
- dataмассив или последовательность массивов
-
Массив или последовательность массивов, хранящих поля, которые нужно добавить к основному массиву.
- dtypesпоследовательность типов данных, необязательно
-
Тип данных или последовательность типов данных. Если None, типы данных оцениваются из
data. - fill_value{float}, необязательно
-
Значение заполнения, используемое для заполнения пропущенных данных в более коротких массивах.
- usemask{False, True}, необязательно
-
Возвращать ли массив с масками.
- asrecarray{False, True}, необязательно
-
Возвращать ли recarray (MaskedRecords).
- numpy.lib.recfunctions.apply_along_fields(func, arr)[source]
-
Применение функции ‘func’ как редукции по полям структурированного массива.
Это аналогично
apply_along_axis, но рассматривает поля структурированного массива как дополнительную ось. Все поля сначала приводится к общему типу, следуя правилам продвижения типов изnumpy.result_type, примененным к типам данных полей.- Parameters
-
- funcфункция
-
Функция для применения к «полевому» измерению. Эта функция должна поддерживать аргумент
axis, например, np.mean, np.sum и т. д. - arrndarray
-
Структурированный массив, к которому нужно применить func.
- Returns
-
- outndarray
-
Результат операции редукции.
Примеры
>>> from numpy.lib import recfunctions as rfn >>> b = np.array([(1, 2, 5), (4, 5, 7), (7, 8 ,11), (10, 11, 12)], ... dtype=[('x', 'i4'), ('y', 'f4'), ('z', 'f8')]) >>> rfn.apply_along_fields(np.mean, b) array([ 2.66666667, 5.33333333, 8.66666667, 11. ]) >>> rfn.apply_along_fields(np.mean, b[['x', 'z']]) array([ 3. , 5.5, 9. , 11. ])
- numpy.lib.recfunctions.assign_fields_by_name(dst, src, zero_unassigned=True)[source]
-
Присваивание значений из одного структурированного массива в другой по имени поля.
Обычно в numpy >= 1.14 присваивание одного структурированного массива другому копирует поля «по позиции», т. е. первое поле из src копируется в первое поле dst и т. д., независимо от имени поля.
Эта функция вместо этого копирует «по имени поля», таким образом поля в dst присваиваются из поля с таким же именем в src. Это рекурсивно применяется для вложенных структур. Именно так работало присваивание структур в numpy >= 1.6 и <= 1.13.
- Parameters
-
- dstndarray
- srcndarray
-
Исходные и целевые массивы при присваивании.
- zero_unassignedbool, необязательно
-
Если True, поля в dst, для которых не было соответствующего поля в src, заполняются значением 0 (ноль). Такое поведение было в numpy <= 1.13. Если False, эти поля не изменяются.
- numpy.lib.recfunctions.drop_fields(base, drop_names, usemask=True, asrecarray=False)[source]
-
Возвращает новый массив с удаленными полями из
drop_names.Поддерживаются вложенные поля.
Изменено в версии 1.18.0:
drop_fieldsвозвращает массив с 0 полями, если все поля удалены, а не возвращаетNoneкак раньше.- Parameters
-
- basearray
-
Входной массив
- drop_namesстрока или последовательность
-
Строка или последовательность строк, соответствующие именам полей для удаления.
- usemask{False, True}, необязательно
-
Возвращать ли массив с масками?
- asrecarrayстрока или последовательность, необязательно
-
Возвращать ли recarray или mrecarray (
asrecarray=True). Или обычный ndarray или массив с масками и гибким типом данных. По умолчанию False.
Примеры
>>> from numpy.lib import recfunctions as rfn >>> a = np.array([(1, (2, 3.0)), (4, (5, 6.0))], ... dtype=[('a', np.int64), ('b', [('ba', np.double), ('bb', np.int64)])]) >>> rfn.drop_fields(a, 'a') array([((2., 3),), ((5., 6),)], dtype=[('b', [('ba', '<f8'), ('bb', '<i8')])]) >>> rfn.drop_fields(a, 'ba') array([(1, (3,)), (4, (6,))], dtype=[('a', '<i8'), ('b', [('bb', '<i8')])]) >>> rfn.drop_fields(a, ['ba', 'bb']) array([(1,), (4,)], dtype=[('a', '<i8')])
- numpy.lib.recfunctions.find_duplicates(a, key=None, ignoremask=True, return_index=False)[source]
-
Найти дубликаты в структурированном массиве по заданному ключу
- Параметры
-
- aarray-like
-
Входной массив
- key{строка, None}, необязательно
-
Имя полей, по которым проверять дубликаты. Если None, поиск выполняется по записям
- ignoremask{True, False}, необязательно
-
Указывает, следует ли игнорировать данные с маской или рассматривать их как дубликаты.
- return_index{False, True}, необязательно
-
Указывает, следует ли возвращать индексы дублирующихся значений.
Примеры
>>> from numpy.lib import recfunctions as rfn >>> ndtype = [('a', int)] >>> a = np.ma.array([1, 1, 1, 2, 2, 3, 3], ... mask=[0, 0, 1, 0, 0, 0, 1]).view(ndtype) >>> rfn.find_duplicates(a, ignoremask=True, return_index=True) (masked_array(data=[(1,), (1,), (2,), (2,)], mask=[(False,), (False,), (False,), (False,)], fill_value=(999999,), dtype=[('a', '<i8')]), array([0, 1, 3, 4]))
- numpy.lib.recfunctions.flatten_descr(ndtype)[source]
-
Распаковать описание структурированного типа данных.
Примеры
>>> from numpy.lib import recfunctions as rfn >>> ndtype = np.dtype([('a', '<i4'), ('b', [('ba', '<f8'), ('bb', '<i4')])]) >>> rfn.flatten_descr(ndtype) (('a', dtype('int32')), ('ba', dtype('float64')), ('bb', dtype('int32')))
- numpy.lib.recfunctions.get_fieldstructure(adtype, lastname=None, parents=None)[source]
-
Возвращает словарь с полями, индексирующими списки их родительских полей.
Эта функция используется для упрощения доступа к полям, вложенным в другие поля.
- Параметры
-
- adtypenp.dtype
-
Входной тип данных
- lastnameнеобязательно
-
Имя последнего обработанного поля (используется во время рекурсии).
- parentsсловарь
-
Словарь родительских полей (используется во время рекурсии).
Примеры
>>> from numpy.lib import recfunctions as rfn >>> ndtype = np.dtype([('A', int), ... ('B', [('BA', int), ... ('BB', [('BBA', int), ('BBB', int)])])]) >>> rfn.get_fieldstructure(ndtype) ... # XXX: possible regression, order of BBA and BBB is swapped {'A': [], 'B': [], 'BA': ['B'], 'BB': ['B'], 'BBA': ['B', 'BB'], 'BBB': ['B', 'BB']}
- numpy.lib.recfunctions.get_names(adtype)[source]
-
Возвращает имена полей входного типа данных в виде кортежа.
- Параметры
-
- adtypedtype
-
Входной тип данных
Примеры
>>> from numpy.lib import recfunctions as rfn >>> rfn.get_names(np.empty((1,), dtype=int)) Traceback (most recent call last): ... AttributeError: 'numpy.ndarray' object has no attribute 'names'>>> rfn.get_names(np.empty((1,), dtype=[('A',int), ('B', float)])) Traceback (most recent call last): ... AttributeError: 'numpy.ndarray' object has no attribute 'names' >>> adtype = np.dtype([('a', int), ('b', [('ba', int), ('bb', int)])]) >>> rfn.get_names(adtype) ('a', ('b', ('ba', 'bb')))
- numpy.lib.recfunctions.get_names_flat(adtype)[source]
-
Возвращает имена полей входного типа данных в виде кортежа. Вложенная структура предварительно сплющивается.
- Параметры
-
- adtypedtype
-
Входной тип данных
Примеры
>>> from numpy.lib import recfunctions as rfn >>> rfn.get_names_flat(np.empty((1,), dtype=int)) is None Traceback (most recent call last): ... AttributeError: 'numpy.ndarray' object has no attribute 'names' >>> rfn.get_names_flat(np.empty((1,), dtype=[('A',int), ('B', float)])) Traceback (most recent call last): ... AttributeError: 'numpy.ndarray' object has no attribute 'names' >>> adtype = np.dtype([('a', int), ('b', [('ba', int), ('bb', int)])]) >>> rfn.get_names_flat(adtype) ('a', 'b', 'ba', 'bb')
- numpy.lib.recfunctions.join_by(key, r1, r2, jointype='inner', r1postfix='1', r2postfix='2', defaults=None, usemask=True, asrecarray=False)[source]
-
Объединить массивы
r1иr2по ключуkey.Ключ должен быть либо строкой, либо последовательностью строк, соответствующих полям, используемым для объединения массива. Исключение возникает, если поле
keyне найдено в двух входных массивах. Ниr1, ниr2не должны содержать дубликатов поkey: наличие дубликатов сделает вывод довольно ненадежным. Обратите внимание, что дубликаты не ищутся алгоритмом.- Параметры
-
- key{строка, последовательность}
-
Строка или последовательность строк, соответствующих полям, используемым для сравнения.
- r1, r2массивы
-
Структурированные массивы.
- jointype{‘inner’, ‘outer’, ‘leftouter’}, необязательно
-
Если ‘inner’, возвращает элементы, общие для r1 и r2. Если ‘outer’, возвращает общие элементы, а также элементы r1, отсутствующие в r2, и элементы r2, отсутствующие в r1. Если ‘leftouter’, возвращает общие элементы и элементы r1, отсутствующие в r2.
- r1postfixстрока, необязательно
-
Строка, добавляемая к именам полей r1, присутствующим в r2, но отсутствующим в ключе.
- r2postfixстрока, необязательно
-
Строка, добавляемая к именам полей r2, присутствующим в r1, но отсутствующим в ключе.
- defaults{словарь}, необязательно
-
Словарь, сопоставляющий имена полей соответствующим значениям по умолчанию.
- usemask{True, False}, необязательно
-
Указывает, следует ли возвращать MaskedArray (или MaskedRecords, если
asrecarray==True) или ndarray. - asrecarray{False, True}, необязательно
-
Указывает, следует ли возвращать recarray (или MaskedRecords, если
usemask==True) или просто массив гибкого типа.
Примечания
- Вывод отсортирован по ключу.
- Временной массив формируется путем удаления полей, не входящих в ключ для двух массивов, и конкатенации результата. Затем этот массив сортируется, и выбираются общие записи. Вывод конструируется путем заполнения полей выбранными записями. Соответствие не сохраняется, если есть некоторые дубликаты…
- numpy.lib.recfunctions.merge_arrays(seqarrays, fill_value=- 1, flatten=False, usemask=False, asrecarray=False)[source]
-
Объединение массивов по полям.
- Параметры
-
- seqarraysпоследовательность ndarrays
-
Последовательность массивов
- fill_value{float}, необязательно
-
Значение заполнения, используемое для заполнения пропущенных данных в более коротких массивах.
- flatten{False, True}, необязательно
-
Определяет, нужно ли сжимать вложенные поля.
- usemask{False, True}, необязательно
-
Определяет, нужно ли возвращать массив с маской.
- asrecarray{False, True}, необязательно
-
Определяет, нужно ли возвращать recarray (MaskedRecords).
Примечания
-
Без маски пропущенное значение будет заполнено значением, зависящим от его типа:
-
-1для целых чисел -
-1.0для чисел с плавающей точкой -
'-'для символов -
'-1'для строк -
Trueдля логических значений
-
- XXX: Эти значения получены эмпирически
Примеры
>>> from numpy.lib import recfunctions as rfn >>> rfn.merge_arrays((np.array([1, 2]), np.array([10., 20., 30.]))) array([( 1, 10.), ( 2, 20.), (-1, 30.)], dtype=[('f0', '<i8'), ('f1', '<f8')])>>> rfn.merge_arrays((np.array([1, 2], dtype=np.int64), ... np.array([10., 20., 30.])), usemask=False) array([(1, 10.0), (2, 20.0), (-1, 30.0)], dtype=[('f0', '<i8'), ('f1', '<f8')]) >>> rfn.merge_arrays((np.array([1, 2]).view([('a', np.int64)]), ... np.array([10., 20., 30.])), ... usemask=False, asrecarray=True) rec.array([( 1, 10.), ( 2, 20.), (-1, 30.)], dtype=[('a', '<i8'), ('f1', '<f8')])
- numpy.lib.recfunctions.rec_append_fields(base, names, data, dtypes=None)[source]
-
Добавление новых полей к существующему массиву.
Имена полей задаются с помощью
namesаргументов, соответствующие значения с помощьюdataаргументов. Если добавляется единственное поле,names,dataиdtypesне должны быть списками, а просто значениями.- Параметры
-
- baseмассив
-
Входной массив для расширения.
- namesстрока, последовательность
-
Строка или последовательность строк, соответствующих именам новых полей.
- dataмассив или последовательность массивов
-
Массив или последовательность массивов, хранящих поля для добавления в базовый массив.
- dtypesпоследовательность типов данных, необязательно
-
Тип данных или последовательность типов данных. Если None, типы данных оцениваются по
data.
- Возвращает
-
- appended_arraynp.recarray
См. также
- numpy.lib.recfunctions.rec_drop_fields(base, drop_names)[source]
-
Возвращает новый numpy.recarray с удаленными полями, указанными в
drop_names.
- numpy.lib.recfunctions.rec_join(key, r1, r2, jointype='inner', r1postfix='1', r2postfix='2', defaults=None)[source]
-
Объединение массивов
r1иr2по ключам. Альтернатива join_by, которая всегда возвращает np.recarray.См. также
join_by-
эквивалентная функция
- numpy.lib.recfunctions.recursive_fill_fields(input, output)[source]
-
Заполняет поля из output полями из input с поддержкой вложенных структур.
- Параметры
-
- inputndarray
-
Входной массив.
- outputndarray
-
Выходной массив.
Примечания
-
outputдолжен быть как минимум такого же размера, какinput
Примеры
>>> from numpy.lib import recfunctions as rfn >>> a = np.array([(1, 10.), (2, 20.)], dtype=[('A', np.int64), ('B', np.float64)]) >>> b = np.zeros((3,), dtype=a.dtype) >>> rfn.recursive_fill_fields(a, b) array([(1, 10.), (2, 20.), (0, 0.)], dtype=[('A', '<i8'), ('B', '<f8')])
- numpy.lib.recfunctions.rename_fields(base, namemapper)[source]
-
Переименование полей из массива с гибким типом данных ndarray или recarray.
Поддерживаются вложенные поля.
- Параметры
-
- basendarray
-
Входной массив, поля которого нужно изменить.
- namemapperсловарь
-
Словарь, сопоставляющий старые имена полей с их новыми версиями.
Примеры
>>> from numpy.lib import recfunctions as rfn >>> a = np.array([(1, (2, [3.0, 30.])), (4, (5, [6.0, 60.]))], ... dtype=[('a', int),('b', [('ba', float), ('bb', (float, 2))])]) >>> rfn.rename_fields(a, {'a':'A', 'bb':'BB'}) array([(1, (2., [ 3., 30.])), (4, (5., [ 6., 60.]))], dtype=[('A', '<i8'), ('b', [('ba', '<f8'), ('BB', '<f8', (2,))])])
- numpy.lib.recfunctions.repack_fields(a, align=False, recurse=False)[source]
-
Переупаковка полей структурированного массива или типа данных в памяти.
Формат хранения структурированных типов данных позволяет расположить поля с произвольными байтовыми смещениями. Это означает, что поля могут быть разделены байтами заполнения, их смещения могут быть не монотонно возрастающими, и они могут перекрываться.
Этот метод устраняет любые перекрытия и переупорядочивает поля в памяти так, чтобы их байтовые смещения возрастали, и добавляет или удаляет байты заполнения в зависимости от параметра
align, который работает так же, как и параметрalignвnp.dtype.Если
align=False, этот метод создает «упакованный» формат хранения, в котором каждое поле начинается с байта, на котором закончилось предыдущее поле, а любые байты заполнения удаляются.Если
align=True, этот метод создает «выровненный» формат хранения, в котором смещение каждого поля является кратным его выравниванию, а общий размер элемента — кратным наибольшему выравниванию, добавляя при необходимости байты заполнения.- Параметры
-
- andarray или dtype
-
массив или тип данных для переупаковки полей.
- alignboolean
-
Если True, используйте «выровненный» формат хранения, иначе используйте «упакованный» формат.
- recurseboolean
-
Если True, также переупаковываются вложенные структуры.
- Возвращает
-
- repackedndarray или dtype
-
Копия
aс переупакованными полями илиa, если переупаковка не требуется.
Примеры
>>> from numpy.lib import recfunctions as rfn >>> def print_offsets(d): ... print("offsets:", [d.fields[name][1] for name in d.names]) ... print("itemsize:", d.itemsize) ... >>> dt = np.dtype('u1, <i8, <f8', align=True) >>> dt dtype({'names':['f0','f1','f2'], 'formats':['u1','<i8','<f8'], 'offsets':[0,8,16], 'itemsize':24}, align=True) >>> print_offsets(dt) offsets: [0, 8, 16] itemsize: 24 >>> packed_dt = rfn.repack_fields(dt) >>> packed_dt dtype([('f0', 'u1'), ('f1', '<i8'), ('f2', '<f8')]) >>> print_offsets(packed_dt) offsets: [0, 1, 9] itemsize: 17
- numpy.lib.recfunctions.require_fields(array, required_dtype)[source]
-
Преобразует структурированный массив в новый тип данных, используя присваивание по имени поля.
Эта функция присваивает значения из старого массива в новый по имени, поэтому значение поля в выходном массиве является значением поля с тем же именем в исходном массиве. Это приводит к созданию нового ndarray, содержащего только поля, «требуемые» типом данных required_dtype.
Если имя поля в required_dtype отсутствует в входном массиве, это поле создается и устанавливается в 0 в выходном массиве.
- Параметры
-
- andarray
-
массив для преобразования
- required_dtypedtype
-
тип данных для выходного массива
- Возвращает
-
- outndarray
-
массив с новым типом данных, значения полей скопированы из полей входного массива с тем же именем
Примеры
>>> from numpy.lib import recfunctions as rfn >>> a = np.ones(4, dtype=[('a', 'i4'), ('b', 'f8'), ('c', 'u1')]) >>> rfn.require_fields(a, [('b', 'f4'), ('c', 'u1')]) array([(1., 1), (1., 1), (1., 1), (1., 1)], dtype=[('b', '<f4'), ('c', 'u1')]) >>> rfn.require_fields(a, [('b', 'f4'), ('newf', 'u1')]) array([(1., 0), (1., 0), (1., 0), (1., 0)], dtype=[('b', '<f4'), ('newf', 'u1')])
- numpy.lib.recfunctions.stack_arrays(arrays, defaults=None, usemask=True, asrecarray=False, autoconvert=False)[source]
-
Наложение массивов поле за полем
- Параметры
-
- arraysмассив или последовательность
-
Последовательность входных массивов.
- defaultsсловарь, необязательно
-
Словарь, сопоставляющий имена полей соответствующим значениям по умолчанию.
- usemask{True, False}, необязательно
-
Возвратить MaskedArray (или MaskedRecords, если
asrecarray==True) или ndarray. - asrecarray{False, True}, необязательно
-
Возвратить recarray (или MaskedRecords, если
usemask==True) или просто массив гибкого типа. - autoconvert{False, True}, необязательно
-
Автоматически ли преобразовать тип поля к максимальному.
Примеры
>>> from numpy.lib import recfunctions as rfn >>> x = np.array([1, 2,]) >>> rfn.stack_arrays(x) is x True >>> z = np.array([('A', 1), ('B', 2)], dtype=[('A', '|S3'), ('B', float)]) >>> zz = np.array([('a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)], ... dtype=[('A', '|S3'), ('B', np.double), ('C', np.double)]) >>> test = rfn.stack_arrays((z,zz)) >>> test masked_array(data=[(b'A', 1.0, --), (b'B', 2.0, --), (b'a', 10.0, 100.0), (b'b', 20.0, 200.0), (b'c', 30.0, 300.0)], mask=[(False, False, True), (False, False, True), (False, False, False), (False, False, False), (False, False, False)], fill_value=(b'N/A', 1.e+20, 1.e+20), dtype=[('A', 'S3'), ('B', '<f8'), ('C', '<f8')])
- numpy.lib.recfunctions.structured_to_unstructured(arr, dtype=None, copy=False, casting='unsafe')[source]
-
Преобразует n-мерный структурированный массив в (n+1)-мерный неструктурированный массив.
Новый массив будет иметь новую последнюю размерность, равную количеству элементов поля входного массива. Если не указано, тип данных выходного массива определяется правилами повышения типа NumPy, примененными ко всем типам данных полей.
Вложенные поля, а также каждый элемент любых полей подмассивов считаются одним элементом поля.
- Параметры
-
- arrndarray
-
Структурированный массив или тип данных для преобразования. Не может содержать тип данных object.
- dtypedtype, необязательно
-
Тип данных выходного неструктурированного массива.
- copybool, необязательно
-
См. аргумент copy в
ndarray.astype. Если True, всегда возвращает копию. Если False и требованияdtypeвыполнены, возвращается представление. - casting{‘no’, ‘equiv’, ‘safe’, ‘same_kind’, ‘unsafe’}, необязательно
-
См. аргумент casting в
ndarray.astype. Управляет типом преобразования данных.
- Возвращает
-
- unstructuredndarray
-
Неструктурированный массив с одной дополнительной размерностью.
Примеры
>>> from numpy.lib import recfunctions as rfn >>> a = np.zeros(4, dtype=[('a', 'i4'), ('b', 'f4,u2'), ('c', 'f4', 2)]) >>> a array([(0, (0., 0), [0., 0.]), (0, (0., 0), [0., 0.]), (0, (0., 0), [0., 0.]), (0, (0., 0), [0., 0.])], dtype=[('a', '<i4'), ('b', [('f0', '<f4'), ('f1', '<u2')]), ('c', '<f4', (2,))]) >>> rfn.structured_to_unstructured(a) array([[0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.]])>>> b = np.array([(1, 2, 5), (4, 5, 7), (7, 8 ,11), (10, 11, 12)], ... dtype=[('x', 'i4'), ('y', 'f4'), ('z', 'f8')]) >>> np.mean(rfn.structured_to_unstructured(b[['x', 'z']]), axis=-1) array([ 3. , 5.5, 9. , 11. ])
- numpy.lib.recfunctions.unstructured_to_structured(arr, dtype=None, names=None, align=False, copy=False, casting='unsafe')[source]
-
Преобразует n-мерный неструктурированный массив в (n-1)-мерный структурированный массив.
Последнее измерение входного массива преобразуется в структуру, с количеством элементов поля, равным размеру последнего измерения входного массива. По умолчанию все поля вывода имеют тип данных входного массива, но вместо этого можно указать структурированный тип данных вывода с равным количеством элементов поля.
Вложенные поля, а также каждый элемент любого подмассива полей, все учитываются в количестве элементов поля.
- Параметры
-
- arrndarray
-
Неструктурированный массив или тип данных для преобразования.
- dtypedtype, необязательно
-
Структурированный тип данных выходного массива
- namesсписок строк, необязательно
-
Если dtype не указан, это определяет имена полей для выходного типа данных в порядке. Типы данных полей будут такими же, как у входного массива.
- alignboolean, необязательно
-
Создавать ли выровненную структуру памяти.
- copybool, необязательно
-
См. аргумент copy в
ndarray.astype. Если true, всегда возвращает копию. Если false, иdtypeтребования выполняются, возвращается представление. - casting{‘no’, ‘equiv’, ‘safe’, ‘same_kind’, ‘unsafe’}, необязательно
-
См. аргумент casting в
ndarray.astype. Управляет видом преобразования данных.
- Возвращает
-
- structuredndarray
-
Структурированный массив с меньшим числом измерений.
Примеры
>>> from numpy.lib import recfunctions as rfn >>> dt = np.dtype([('a', 'i4'), ('b', 'f4,u2'), ('c', 'f4', 2)]) >>> a = np.arange(20).reshape((4,5)) >>> a array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19]]) >>> rfn.unstructured_to_structured(a, dt) array([( 0, ( 1., 2), [ 3., 4.]), ( 5, ( 6., 7), [ 8., 9.]), (10, (11., 12), [13., 14.]), (15, (16., 17), [18., 19.])], dtype=[('a', '<i4'), ('b', [('f0', '<f4'), ('f1', '<u2')]), ('c', '<f4', (2,))])
© 2005–2022 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.21/user/basics.rec.html