Структурированные массивы
Введение
Структурированные массивы — это 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 символов или меньше с именем «name», 2. 32-битное целое число с именем «age» и 3. 32-битное число с плавающей точкой с именем «weight».
Если вы индексируете x по позиции 1, вы получите структуру:
>>> x[1]
np.void(('Fido', 3, 27.0), dtype=[('name', '<U10'), ('age', '<i4'), ('weight', '<f4')])
Вы можете получать доступ к отдельным полям структурированного массива и изменять их, индексируя по имени поля:
>>> 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.Необязательное значение «заголовки» должно быть списком заголовков той же длины, что и «имена», см. Заголовки полей ниже.
-
Словарь имен полей
Ключами словаря являются имена полей, а значениями — кортежи, определяющие тип и смещение:
>>> np.dtype({'col1': ('i1', 0), 'col2': ('f4', 1)}) dtype([('col1', 'i1'), ('col2', '<f4')])Эта форма не рекомендуется, так как словари Python не сохраняли порядок в версиях Python до Python 3.6. Заголовки полей Заголовки полей могут быть указаны с использованием 3-х элементов кортежа, см. ниже.
Обработка и отображение структурированных типов данных
Список имен полей структурированного типа данных можно найти в атрибуте names объекта dtype:
>>> d = np.dtype([('x', 'i8'), ('y', 'f4')])
>>> d.names
('x', 'y')
Тип данных каждого отдельного поля можно найти по имени:
>>> d['x']
dtype('int64')
Имена полей могут быть изменены путем присваивания атрибуту names последовательностью строк той же длины.
Объект dtype также имеет атрибут, похожий на словарь, fields, ключами которого являются имена полей (и заголовки полей, см. ниже), а значениями — кортежи, содержащие тип данных и байтовое смещение каждого поля.
>>> d.fields
mappingproxy({'x': (dtype('int64'), 0), 'y': (dtype('float32'), 8)})
И атрибут names, и атрибут fields будут равны None для неструктурированных массивов. Рекомендуемый способ проверки, является ли dtype структурированным, — это использовать if dt.names is not None вместо if dt.names, чтобы учесть dtype с 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 преобразует выровненный dtype или массив в упакованный и наоборот. Она принимает в качестве аргумента dtype или структурированный ndarray и возвращает копию с переупакованными полями с или без заполняющих байтов.
Заголовки полей
Помимо имен полей, поля могут также иметь связанный заголовок, альтернативное имя, которое иногда используется в качестве дополнительного описания или псевдонима для поля. Заголовок можно использовать для индексирования массива, так же как и имя поля.
Для добавления заголовков при использовании формы спецификации dtype в виде списка кортежей имя поля можно указать как кортеж из двух строк вместо одной строки, которая будет заголовком и именем поля соответственно. Например:
>>> np.dtype([(('my title', 'name'), 'f4')])
dtype([(('my title', 'name'), '<f4')])
При использовании первой формы спецификации dtype на основе словаря заголовки могут быть заданы как дополнительный 'titles' ключ, как описано выше. При использовании второй (не рекомендуемой) формы спецификации dtype на основе словаря заголовок можно указать, предоставив кортеж из 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. Этот тип данных похож на «объединение» в языке 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., 0.],
[0., 0.]], dtype=float32)
Присваивание массиву с многопольным индексом изменяет исходный массив:
>>> 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
np.void((1, 2.0, 3.0), dtype=[('f0', '<i4'), ('f1', '<f4'), ('f2', '<f4')])
>>> 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
Таким образом, кортежи можно рассматривать как эквивалент Python для структурированных типов NumPy, так же как обычные целые числа Python являются эквивалентом целочисленных типов NumPy. Структурированные скаляры могут быть преобразованы в кортеж, вызвав numpy.ndarray.item:
>>> scalar.item(), type(scalar.item()) ((1, 4.0, 3.0), <class 'tuple'>)
Просмотр структурированных массивов, содержащих объекты
Для предотвращения перезаписи указателей на объекты в полях типа object, NumPy в настоящее время не допускает представлений структурированных массивов, содержащих объекты.
Сравнение и продвижение структур
Если типы данных двух массивов с пустым структурированным типом равны, проверка равенства массивов приведет к логическому массиву с размерами исходных массивов, со значениями, установленными в True , где все поля соответствующих структур равны:
>>> a = np.array([(1, 1), (2, 2)], dtype=[('a', 'i4'), ('b', 'i4')])
>>> b = np.array([(1, 1), (2, 3)], dtype=[('a', 'i4'), ('b', 'i4')])
>>> a == b
array([True, False])
NumPy будет продвигать типы данных отдельных полей для выполнения сравнения. Поэтому следующее также допустимо (обратите внимание на тип данных 'f4' для поля 'a'):
>>> b = np.array([(1.0, 1), (2.5, 2)], dtype=[("a", "f4"), ("b", "i4")])
>>> a == b
array([True, False])
Для сравнения двух структурированных массивов необходимо возможность их преобразования к общему типу данных, как возвращается numpy.result_type и numpy.promote_types. Это гарантирует, что количество полей, имена полей и имена полей должны точно совпадать. Когда продвижение невозможно, например, из-за несовпадения имён полей, NumPy выдаст ошибку. Продвижение между двумя структурированными типами данных приводит к каноническому типу данных, который гарантирует родной порядок байтов для всех полей:
>>> np.result_type(np.dtype("i,>i"))
dtype([('f0', '<i4'), ('f1', '<i4')])
>>> np.result_type(np.dtype("i,>i"), np.dtype("i,i"))
dtype([('f0', '<i4'), ('f1', '<i4')])
Полученный тип данных при продвижении также гарантированно будет упакован, что означает, что все поля упорядочены непрерывно, и любые ненужные заполнители удаляются:
>>> dt = np.dtype("i1,V3,i4,V1")[["f0", "f2"]]
>>> dt
dtype({'names':['f0','f2'], 'formats':['i1','<i4'], 'offsets':[0,4], 'itemsize':9})
>>> np.result_type(dt)
dtype([('f0', 'i1'), ('f2', '<i4')])
Обратите внимание, что результат выводится без offsets или itemsize , указывающего на отсутствие дополнительного заполнения. Если структурированный тип данных создан с align=True , гарантируя, что dtype.isalignedstruct верно, это свойство сохраняется:
>>> dt = np.dtype("i1,V3,i4,V1", align=True)[["f0", "f2"]]
>>> dt
dtype({'names':['f0','f2'], 'formats':['i1','<i4'], 'offsets':[0,4], 'itemsize':12}, align=True)
>>> np.result_type(dt)
dtype([('f0', 'i1'), ('f2', '<i4')], align=True)
>>> np.result_type(dt).isalignedstruct
True
При продвижении нескольких типов данных результат выравнивается, если любой из входных данных:
>>> np.result_type(np.dtype("i,i"), np.dtype("i,i", align=True))
dtype([('f0', '<i4'), ('f1', '<i4')], align=True)
Операторы < и > всегда возвращают False при сравнении пустых структурированных массивов, и арифметические и побитовые операции не поддерживаются.
Изменено в версии 1.23: До NumPy 1.23 выдавалось предупреждение, и False возвращалось, когда преобразование к общему типу данных не удавалось. Кроме того, продвижение было намного более ограничено: оно отклоняло пример смешанного сравнения с плавающей точкой/целыми числами выше.
Массивы записей
В качестве дополнительной удобной функции numpy предоставляет подкласс ndarray, numpy.recarray, который позволяет обращаться к полям структурированных массивов по атрибуту вместо только по индексу. Массивы записей используют специальный тип данных, numpy.record, который позволяет получать доступ к полям по атрибуту для структурированных скаляров, полученных из массива. Модуль numpy.rec предоставляет функции для создания массивов записей из различных объектов. Дополнительные вспомогательные функции для создания и обработки структурированных массивов можно найти в 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 предоставляет ряд других удобных функций для создания массивов записей, см. процедуры создания массивов записей.
Представление структурированного массива в виде массива записей можно получить, используя соответствующий view:
>>> arr = np.array([(1, 2., 'Hello'), (2, 3., "World")],
... dtype=[('foo', 'i4'),('bar', 'f4'), ('baz', 'S10')])
>>> 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.rec.recarray'>
Обратите внимание, что если поле имеет то же имя, что и атрибут ndarray, то атрибут ndarray имеет приоритет. Такие поля будут недоступны по атрибуту, но по-прежнему доступны по индексу.
Вспомогательные функции для массивов с записями
Набор утилит для работы с массивами структурных данных.
Большинство этих функций были первоначально реализованы Джоном Хантером для matplotlib. Они были переписаны и расширены для удобства.
- numpy.lib.recfunctions.append_fields(base, names, data, dtypes=None, fill_value=-1, usemask=True, asrecarray=False)[source]
-
Добавление новых полей в существующий массив.
Имена полей задаются аргументом
names, соответствующие значения — аргументомdata. Если добавляется одно поле,names,dataиdtypesне должны быть списками, а просто значениями.- Параметры:
-
- baseмассив
-
Вводной массив для расширения.
- namesстрока, последовательность
-
Строка или последовательность строк, соответствующих именам новых полей.
- dataмассив или последовательность массивов
-
Массив или последовательность массивов, хранящих поля для добавления в базовый массив.
- dtypesпоследовательность типов данных, необязательно
-
Тип данных или последовательность типов данных. Если None, типы данных оцениваются по
data. - fill_value{число с плавающей запятой}, необязательно
-
Значение заполнения, используемое для заполнения пропусков в более коротких массивах.
- usemask{False, True}, необязательно
-
Возвращать ли массив с масками.
- asrecarray{False, True}, необязательно
-
Возвращать ли массив с записями (MaskedRecords) или нет.
- numpy.lib.recfunctions.apply_along_fields(func, arr)[source]
-
Применение функции ‘func’ как редукции по полям массива структур.
Это аналогично
numpy.apply_along_axis, но обрабатывает поля массива структур как дополнительную ось. Поля сначала приводятся к общему типу в соответствии с правилами повышения типа изnumpy.result_type, примененными к типам данных полей.- Параметры:
-
- funcфункция
-
Функция, применяемая по размерности «полей». Эта функция должна поддерживать аргумент
axis, какnumpy.mean,numpy.sumи т. д. - arrndarray
-
Массив структурных данных, к которому нужно применить функцию.
- Возвращает:
-
- 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.
- Параметры:
-
- 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, как это было раньше.- Параметры:
-
- baseмассив
-
Входной массив
- drop_namesстрока или последовательность
-
Строка или последовательность строк, соответствующих именам полей для удаления.
- usemask{False, True}, необязательно
-
Возвращать ли массив с масками.
- asrecarrayстрока или последовательность, необязательно
-
Возвращать ли массив с записями или 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=[('A', int)]).dtype) ('A',) >>> rfn.get_names(np.empty((1,), dtype=[('A',int), ('B', float)]).dtype) ('A', 'B') >>> 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=[('A', int)]).dtype) is None False >>> rfn.get_names_flat(np.empty((1,), dtype=[('A',int), ('B', str)]).dtype) ('A', 'B') >>> 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) или просто гибкий массив ndarray.
Примечания
- Вывод отсортирован по ключу.
- Временной массив формируется путём удаления полей, не входящих в ключ для двух массивов, и объединения результата. Этот массив затем сортируется, и выбираются общие записи. Вывод создаётся путём заполнения полей выбранными записями. Соответствие не сохраняется, если есть дубликаты…
- numpy.lib.recfunctions.merge_arrays(seqarrays, fill_value=-1, flatten=False, usemask=False, asrecarray=False)[source]
-
Объединение массивов поле за полем.
- Параметры:
-
- seqarraysпоследовательность ndarray
-
Последовательность массивов
- 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]
-
Заполняет поля из выходного массива полями из входного массива с поддержкой вложенных структур.
- Параметры:
-
- 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кnumpy.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]
-
Наложение массивов поле за полем
- Параметры:
-
- arraysarray или последовательность
-
Последовательность входных массивов.
- defaultsсловарь, необязательно
-
Словарь, сопоставляющий имена полей соответствующим значениям по умолчанию.
- usemask{True, False}, необязательно
-
Возвращать ли MaskedArray (или MaskedRecords в случае
asrecarray==True) или ndarray. - asrecarray{False, True}, необязательно
-
Возвращать ли recarray (или MaskedRecords, если
usemask==True) или просто массив гибкого типа ndarray. - 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', 1e+20, 1e+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, необязательно
-
Если True, всегда возвращает копию. Если False, возвращает представление, если это возможно, например, когда
dtypeи шаги полей подходят и тип массива — один изnumpy.ndarray,numpy.recarrayилиnumpy.memmap.Изменено в версии 1.25.0: Теперь можно вернуть представление, если поля разделены равномерным шагом.
- casting{‘no’, ‘equiv’, ‘safe’, ‘same_kind’, ‘unsafe’}, необязательно
-
См. аргумент casting в
numpy.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 не указан, это определяет имена полей выходного dtype по порядку. Типы данных полей будут такими же, как у входного массива.
- alignboolean, необязательно
-
Создать выровненный макет памяти?
- copybool, необязательно
-
См. аргумент copy в
numpy.ndarray.astype. Если True, всегда возвращает копию. Если False, иdtypeтребования выполнены, возвращается представление. - casting{‘no’, ‘equiv’, ‘safe’, ‘same_kind’, ‘unsafe’}, необязательно
-
См. аргумент casting в
numpy.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–2024 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/2.0/user/basics.rec.html