Структурированные массивы#

Введение#

Структурированные массивы – это 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', '

Здесь x является одномерным массивом длины два, тип данных которого представляет собой структуру с тремя полями: 1. Строка длиной 10 или менее символов с именем 'name', 2. 32-битное целое число с именем 'age' и 3. 32-битное число с плавающей запятой с именем 'weight'.

Если вы индексируете x в позиции 1 вы получаете структуру:

>>> x[1]
np.void(('Fido', 3, 27.0), dtype=[('name', '

Вы можете получать доступ и изменять отдельные поля структурированного массива, индексируя по имени поля:

>>> x['age']
array([9, 3], dtype=int32)
>>> x['age'] = 5
>>> x
array([('Rex', 5, 81.), ('Fido', 5, 27.)],
      dtype=[('name', '

Структурированные типы данных предназначены для имитации 'структур' в языке C и имеют схожую организацию памяти. Они предназначены для взаимодействия с кодом на C и для низкоуровневого управления структурированными буферами, например, для интерпретации двоичных данных. Для этих целей они поддерживают специализированные возможности, такие как подмассивы, вложенные типы данных и объединения, а также позволяют контролировать расположение структуры в памяти.

Пользователям, работающим с табличными данными, например, хранящимися в csv-файлах, могут больше подойти другие проекты pydata, такие как xarray, pandas или DataArray. Они предоставляют высокоуровневый интерфейс для анализа табличных данных и лучше оптимизированы для этого. Например, макет памяти структурированных массивов в numpy, подобный C-структуре, может приводить к плохому поведению кэша в сравнении.

Структурированные типы данных#

Структурированный тип данных можно рассматривать как последовательность байтов определённой длины ( itemsize), который интерпретируется как коллекция полей. Каждое поле имеет имя, тип данных и смещение в байтах внутри структуры. Тип данных поля может быть любым типом данных numpy, включая другие структурированные типы данных, а также может быть тип данных подмассива который ведёт себя как ndarray заданной формы. Смещения полей являются произвольными, и поля могут даже перекрываться. Эти смещения обычно определяются автоматически numpy, но также могут быть указаны вручную.

Создание структурированного типа данных#

Структурированные типы данных могут быть созданы с помощью функции numpy.dtype. Существует 4 альтернативные формы спецификации, которые различаются по гибкости и краткости. Они подробно описаны в Объекты типов данных справочная страница, и в кратком описании они:

  1. Список кортежей, по одному кортежу на поле

    Каждый кортеж имеет вид (fieldname, datatype, shape) где форма необязательна. fieldname является строкой (или кортежем, если используются заголовки, см. Названия полей ниже), datatype может быть любым объектом, преобразуемым в тип данных, и shape является кортежем целых чисел, задающим форму подмассива.

    >>> np.dtype([('x', 'f4'), ('y', np.float32), ('z', 'f4', (2, 2))])
    dtype([('x', '
    

    Если fieldname является пустой строкой '', полю будет присвоено имя по умолчанию вида f#, где # является целочисленным индексом поля, отсчитываемым от 0 слева:

    >>> np.dtype([('x', 'f4'), ('', 'i4'), ('z', 'i8')])
    dtype([('x', '
    

    Байтовые смещения полей внутри структуры и общий размер элементов структуры определяются автоматически.

  2. Строка спецификаций dtype, разделённых запятыми

    В этой сокращённой записи любой из спецификации строкового типа данных может использоваться в строке и разделяться запятыми. Размер элемента и смещения в байтах полей определяются автоматически, а имена полей получают стандартные имена f0, f1, и т.д.

    >>> np.dtype('i8, f4, S3')
    dtype([('f0', '
    >>> np.dtype('3int8, float32, (2, 3)float64')
    dtype([('f0', 'i1', (3,)), ('f1', '
    
  3. Словарь массивов параметров полей

    Это наиболее гибкая форма спецификации, поскольку она позволяет контролировать смещения байтов полей и размер элементов структуры.

    Словарь имеет два обязательных ключа, 'names' и 'formats', и четыре необязательных ключа, 'offsets', 'itemsize', 'aligned' и 'titles'. Значения для 'names' и 'formats' должны быть соответственно списком имён полей и списком спецификаций dtype, одинаковой длины. Необязательное значение 'offsets' должно быть списком целочисленных смещений в байтах, по одному для каждого поля в структуре. Если 'offsets' не задано, смещения определяются автоматически. Необязательное значение 'itemsize' должно быть целым числом, описывающим общий размер в байтах dtype, который должен быть достаточно большим, чтобы содержать все поля.

    >>> np.dtype({'names': ['col1', 'col2'], 'formats': ['i4', 'f4']})
    dtype([('col1', '
    >>> np.dtype({'names': ['col1', 'col2'],
    ...           'formats': ['i4', 'f4'],
    ...           'offsets': [0, 4],
    ...           'itemsize': 12})
    dtype({'names': ['col1', 'col2'], 'formats': ['
    

    Смещения могут быть выбраны так, чтобы поля перекрывались, хотя это означает, что присвоение одному полю может затереть данные любого перекрывающегося поля. За исключением полей numpy.object_ тип не может пересекаться с другими полями из-за риска повреждения внутреннего указателя объекта и последующего разыменования.

    Необязательное значение 'aligned' может быть установлено в True чтобы автоматическое вычисление смещения использовало выровненные смещения (см. Автоматические смещения байтов и выравнивание), как если бы аргумент ключевого слова 'align' numpy.dtype был установлен в True.

    Необязательное значение 'titles' должно быть списком заголовков той же длины, что и 'names', см. Названия полей ниже.

  4. Словарь имён полей

    Ключами словаря являются имена полей, а значениями — кортежи, указывающие тип и смещение:

    >>> np.dtype({'col1': ('i1', 0), 'col2': ('f4', 1)})
    dtype([('col1', 'i1'), ('col2', '
    

    Эта форма не рекомендовалась, потому что словари 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, ключами которого являются имена полей (и Названия полей(см. ниже) и чьи значения являются кортежами, содержащими dtype и смещение в байтах каждого поля.

>>> d.fields
mappingproxy({'x': (dtype('int64'), 0), 'y': (dtype('float32'), 8)})

Оба names и fields атрибуты будут равны None для неструктурированных массивов. Рекомендуемый способ проверки, является ли dtype структурированным, — с помощью если dt.names не равно None вместо если dt.names, чтобы учесть dtypes с 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. Структура также будет иметь завершающее заполнение, добавленное так, чтобы ее itemsize был кратен выравниванию самого большого поля.

>>> 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, для достижения точного соответствия.

Если смещения были указаны с использованием опционального offsets ключ в спецификации типа данных на основе словаря, установка align=True проверит, что смещение каждого поля кратно его размеру и что размер элемента кратен наибольшему размеру поля, и вызовет исключение, если это не так.

Если смещения полей и размер элемента (itemsize) структурированного массива удовлетворяют условиям выравнивания, массив будет иметь ALIGNED flag set.

Удобная функция numpy.lib.recfunctions.repack_fields преобразует выровненный dtype или массив в упакованный и наоборот. Принимает либо dtype, либо структурированный ndarray в качестве аргумента и возвращает копию с переупакованными полями, с байтами заполнения или без них.

Заголовки полей#

В дополнение к именам полей, поля также могут иметь связанный title, альтернативное имя, которое иногда используется как дополнительное описание или псевдоним для поля. Заголовок может использоваться для индексации массива, как и имя поля.

Чтобы добавить заголовки при использовании формы спецификации dtype в виде списка кортежей, имя поля может быть указано как кортеж из двух строк вместо одной строки, которые будут соответственно заголовком поля и именем поля. Например:

>>> np.dtype([(('my title', 'name'), 'f4')])
dtype([(('my title', 'name'), '

При использовании первой формы спецификации на основе словаря заголовки могут быть предоставлены как дополнительный 'titles' ключ, как описано выше. При использовании второго (не рекомендуемого) словарного спецификации заголовок может быть предоставлен путём указания кортежа из 3 элементов (datatype, offset, title) вместо обычного кортежа из 2 элементов:

>>> np.dtype({'name': ('i4', 0, 'my title')})
dtype([(('my title', 'name'), '

The 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-типы как структурированные типы с использованием (base_dtype, dtype) форма спецификации dtype, описанная в Объекты типов данных. Здесь, base_dtype является желаемым базовым dtype, а поля и флаги будут скопированы из dtypeЭтот тип данных похож на 'union' в 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', '

Присваивание скаляров#

Скаляр, присвоенный структурированному элементу, будет присвоен всем полям. Это происходит, когда скаляр присваивается структурированному массиву или когда неструктурированный массив присваивается структурированному массиву:

>>> x = np.zeros(2, dtype='i8, f4, ?, S1')
>>> x[:] = 3
>>> x
array([(3, 3., True, b'3'), (3, 3., True, b'3')],
      dtype=[('f0', '
>>> x[:] = np.arange(2)
>>> x
array([(0, 0., False, b'0'), (1, 1., True, b'1')],
      dtype=[('f0', '

Структурированные массивы также могут быть присвоены неструктурированным массивам, но только если структурированный тип данных имеет только одно поле:

>>> 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', '

Присваивание из других структурированных массивов#

Присваивание между двумя структурированными массивами происходит так, как если бы элементы источника были преобразованы в кортежи и затем присвоены элементам назначения. То есть первое поле исходного массива присваивается первому полю массива назначения, второе поле аналогично и так далее, независимо от имен полей. Структурированные массивы с разным количеством полей не могут быть присвоены друг другу. Байты структуры назначения, не включенные ни в одно из полей, остаются неизменными.

>>> 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', '

Присваивание с участием подмассивов#

При присваивании полям, которые являются подмассивами, присваиваемое значение сначала будет распространено на форму подмассива.

Индексация структурированных массивов#

Доступ к отдельным полям#

Отдельные поля структурированного массива могут быть доступны и изменены путём индексации массива с именем поля.

>>> 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', '

Результирующий массив является представлением исходного массива. Он использует те же области памяти, и запись в представление изменит исходный массив.

>>> y = x['bar']
>>> y[:] = 11
>>> x
array([(10, 11.), (10, 11.)],
      dtype=[('foo', '

Это представление имеет тот же dtype и itemsize, что и индексированное поле, поэтому оно обычно является неструктурированным массивом, за исключением случая вложенных структур.

>>> 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': ['

Присваивание представлению изменяет исходный массив. Поля представления будут в порядке их индексации. Обратите внимание, что в отличие от индексации одного поля, dtype представления имеет тот же размер элемента, что и исходный массив, и поля находятся на тех же смещениях, что и в исходном массиве, а неиндексированные поля просто отсутствуют.

Предупреждение

В 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 "", line 1, in 
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', '

Это подчиняется правилам присваивания структурированных массивов, описанным выше. Например, это означает, что можно поменять значения двух полей, используя соответствующие индексы нескольких полей:

>>> 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', '
>>> type(scalar)

В отличие от других скаляров 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', '

Аналогично кортежам, структурированные скаляры также можно индексировать целым числом:

>>> scalar = np.array([(1, 2., 3.)], dtype='i, f, f')[0]
>>> scalar[0]
np.int32(1)
>>> scalar[1] = 4

Таким образом, кортежи можно рассматривать как эквивалент Python структурированным типам numpy, подобно тому, как целые числа Python являются эквивалентом целочисленным типам numpy. Структурированные скаляры могут быть преобразованы в кортеж путем вызова numpy.ndarray.item:

>>> scalar.item(), type(scalar.item())
((1, 4.0, 3.0), )

Просмотр структурированных массивов, содержащих объекты#

Чтобы предотвратить перезапись указателей объектов в полях object типа, numpy в настоящее время не разрешает представления структурированных массивов, содержащих объекты.

Сравнение и приведение структур#

Если типы данных двух void структурированных массивов равны, проверка равенства массивов приведет к логическому массиву с размерами исходных массивов, где элементы установлены в 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])

Для сравнения двух структурированных массивов необходимо иметь возможность привести их к общему dtype, возвращаемому numpy.result_type и numpy.promote_types. Это обеспечивает, что количество полей, имена полей и заголовки полей должны точно совпадать. Когда приведение невозможно, например из-за несовпадения имён полей, NumPy вызовет ошибку. Приведение между двумя структурированными типами данных приводит к каноническому типу данных, который гарантирует собственный порядок байтов для всех полей:

>>> np.result_type(np.dtype("i,>i"))
dtype([('f0', '
>>> np.result_type(np.dtype("i,>i"), np.dtype("i,i"))
dtype([('f0', '

Результирующий тип данных после приведения также гарантированно упакован, что означает, что все поля упорядочены непрерывно и любой ненужный отступ удален:

>>> dt = np.dtype("i1,V3,i4,V1")[["f0", "f2"]]
>>> dt
dtype({'names': ['f0', 'f2'], 'formats': ['i1', '
>>> np.result_type(dt)
dtype([('f0', 'i1'), ('f2', '

Обратите внимание, что результат выводится без offsets или itemsize указывая на отсутствие дополнительного заполнения. Если структурированный dtype создан с align=True обеспечивая, что dtype.isalignedstruct истинно, это свойство сохраняется:

>>> dt = np.dtype("i1,V3,i4,V1", align=True)[["f0", "f2"]]
>>> dt
dtype({'names': ['f0', 'f2'], 'formats': ['i1', '

>>> np.result_type(dt)
dtype([('f0', 'i1'), ('f2', '
>>> np.result_type(dt).isalignedstruct
True

При повышении нескольких типов данных результат выравнивается, если любой из входных данных:

>>> np.result_type(np.dtype("i,i"), np.dtype("i,i", align=True))
dtype([('f0', '

The < и > операторы всегда возвращают False при сравнении void структурированных массивов, а арифметические и побитовые операции не поддерживаются.

Изменено в версии 1.23: До NumPy 1.23 выдавалось предупреждение и False возвращается, когда приведение к общему типу данных не удалось. Кроме того, приведение было гораздо более ограниченным: оно отклоняло смешанный пример сравнения float/integer выше.

Записывающие массивы#

В качестве дополнительного удобства numpy предоставляет подкласс ndarray, numpy.recarray которая позволяет обращаться к полям структурированных массивов через атрибут, а не только по индексу. Массивы записей используют специальный тип данных, numpy.record, который позволяет доступ к полям через атрибуты у структурированных скаляров, полученных из массива. numpy.rec модуль предоставляет функции для создания recarrays из различных объектов. Дополнительные вспомогательные функции для создания и управления структурированными массивами можно найти в 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', '
>>> 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)

The 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 тип данных, поэтому dtype может быть опущен в представлении:

>>> recordarr = arr.view(np.recarray)
>>> recordarr.dtype
dtype((numpy.record, [('foo', '

Чтобы вернуться к обычному ndarray, необходимо сбросить как dtype, так и тип. Следующее представление делает это, учитывая необычный случай, когда 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)

>>> type(recordarr.bar)

Обратите внимание, что если поле имеет то же имя, что и атрибут ndarray, приоритет имеет атрибут ndarray. Такие поля будут недоступны по атрибуту, но все еще доступны по индексу.

Вспомогательные функции Recarray#

Набор утилит для работы со структурированными массивами.

Большинство этих функций изначально были реализованы Джоном Хантером для matplotlib. Они были переписаны и расширены для удобства.

numpy.lib.recfunctions.append_fields(основание, names, данные, dtypes=None, fill_value=-1, usemask=True, asrecarray=False)[источник]#

Добавить новые поля в существующий массив.

Имена полей задаются с помощью names аргументы, соответствующие значения с данные аргументы. Если добавляется одно поле, names, данные и dtypes не обязаны быть списками, а просто значениями.

Параметры:
основаниемассив

Входной массив для расширения.

namesстрока, последовательность

Строка или последовательность строк, соответствующих именам новых полей.

данныемассив или последовательность массивов

Массив или последовательность массивов, хранящих поля для добавления к базе.

dtypesпоследовательность типов данных, опционально

Тип данных или последовательность типов данных. Если None, типы данных оцениваются из данные.

fill_value{float}, опционально

Значение заполнения, используемое для дополнения отсутствующих данных в более коротких массивах.

usemask{False, True}, опционально

Возвращать ли маскированный массив или нет.

asrecarray{False, True}, опционально

Возвращать ли recarray (MaskedRecords) или нет.

numpy.lib.recfunctions.apply_along_fields(функция, arr)[источник]#

Применить функцию 'func' как редукцию по полям структурированного массива.

Это похоже на numpy.apply_along_axis, но рассматривает поля структурированного массива как дополнительную ось. Все поля сначала приводятся к общему типу в соответствии с правилами продвижения типов из numpy.result_type применён к типам данных поля.

Параметры:
функцияфункция

Функция для применения к измерению «поля». Эта функция должна поддерживать ось аргумент, как numpy.mean, numpy.sum, и т.д.

arrndarray

Структурированный массив, к которому применяется функция.

Возвращает:
выходndarray

Результат операции редукции

Примеры

>>> import numpy as np
>>> 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)[источник]#

Присваивает значения из одного структурированного массива другому по имени поля.

Обычно в numpy >= 1.14 присвоение одного структурированного массива другому копирует поля «по позиции», что означает, что первое поле из источника копируется в первое поле приёмника и так далее, независимо от имени поля.

Эта функция копирует "по имени поля", так что поля в dst присваиваются из одноименного поля в src. Это применяется рекурсивно для вложенных структур. Так работало присваивание структур в numpy >= 1.6 до <= 1.13.

Параметры:
dstndarray
srcndarray

Исходные и целевые массивы во время присваивания.

zero_unassignedbool, необязательно

Если True, поля в dst, для которых не было соответствующего поля в src, заполняются значением 0 (ноль). Это было поведением numpy <= 1.13. Если False, эти поля не изменяются.

numpy.lib.recfunctions.drop_fields(основание, drop_names, usemask=True, asrecarray=False)[источник]#

Вернуть новый массив с полями в drop_names удален.

Поддерживаются вложенные поля.

Параметры:
основаниемассив

Входной массив

drop_namesстрока или последовательность

Строка или последовательность строк, соответствующих именам полей для удаления.

usemask{False, True}, опционально

Возвращать ли маскированный массив или нет.

asrecarrayстрока или последовательность, опционально

Возвращать ли recarray или mrecarray (asrecarray=True) или простой ndarray или маскированный массив с гибким типом данных. По умолчанию False.

Примеры

>>> import numpy as np
>>> 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', '
>>> rfn.drop_fields(a, 'ba')
array([(1, (3,)), (4, (6,))], dtype=[('a', '
>>> rfn.drop_fields(a, ['ba', 'bb'])
array([(1,), (4,)], dtype=[('a', '
numpy.lib.recfunctions.find_duplicates(a, ключ=None, ignoremask=True, return_index=False)[источник]#

Найти дубликаты в структурированном массиве по заданному ключу

Параметры:
aarray-like

Входной массив

ключ{string, None}, опционально

Имена полей, по которым проверяются дубликаты. Если None, поиск выполняется по записям

ignoremask{True, False}, опционально

Следует ли игнорировать замаскированные данные или считать их дубликатами.

return_index{False, True}, опционально

Возвращать ли индексы дублированных значений.

Примеры

>>> import numpy as np
>>> 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', '
numpy.lib.recfunctions.flatten_descr(ndtype)[источник]#

Развернуть описание структурированного типа данных.

Примеры

>>> import numpy as np
>>> from numpy.lib import recfunctions as rfn
>>> ndtype = np.dtype([('a', '), ('b', [('ba', '), ('bb', ')])])
>>> rfn.flatten_descr(ndtype)
(('a', dtype('int32')), ('ba', dtype('float64')), ('bb', dtype('int32')))
numpy.lib.recfunctions.get_fieldstructure(adtype, фамилия=None, родители=None)[источник]#

Возвращает словарь с полями, индексирующими списки их родительских полей.

Эта функция используется для упрощения доступа к полям, вложенным в другие поля.

Параметры:
adtypenp.dtype

Входной тип данных

фамилиянеобязательный

Последнее обработанное имя поля (используется внутренне во время рекурсии).

родителисловарь

Словарь родительских полей (используется внутренне во время рекурсии).

Примеры

>>> import numpy as np
>>> 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)[источник]#

Возвращает имена полей входного типа данных в виде кортежа. Входной тип данных должен иметь поля, иначе возникает ошибка.

Параметры:
adtypedtype

Входной тип данных

Примеры

>>> import numpy as np
>>> 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)[источник]#

Возвращает имена полей входного типа данных в виде кортежа. Входной тип данных должен иметь поля, иначе будет вызвана ошибка. Вложенные структуры предварительно сглаживаются.

Параметры:
adtypedtype

Входной тип данных

Примеры

>>> import numpy as np
>>> 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(ключ, r1, r2, jointype='inner', r1postfix='1', r2postfix='2', значения по умолчанию=None, usemask=True, asrecarray=False)[источник]#

Объединение массивов r1 и r2 по ключу ключ.

Ключ должен быть либо строкой, либо последовательностью строк, соответствующих полям, используемым для соединения массива. Исключение возникает, если ключ поле не может быть найдено в двух входных массивах. Ни один из r1 ни r2 должен иметь любые дубликаты вдоль ключ: наличие дубликатов сделает вывод весьма ненадежным. Обратите внимание, что алгоритм не ищет дубликаты.

Параметры:
ключ{string, sequence}

Строка или последовательность строк, соответствующих полям, используемым для сравнения.

r1, r2массивы

Структурированные массивы.

jointype{‘inner’, ‘outer’, ‘leftouter’}, необязательно

Если 'inner', возвращает элементы, общие для r1 и r2. Если 'outer', возвращает общие элементы, а также элементы r1, не входящие в r2, и элементы, не входящие в r2. Если 'leftouter', возвращает общие элементы и элементы r1, не входящие в r2.

r1postfixstring, optional

Строка, добавляемая к именам полей r1, которые присутствуют в r2, но отсутствуют в ключе.

r2postfixstring, optional

Строка, добавляемая к именам полей r2, которые присутствуют в r1, но отсутствуют в ключе.

значения по умолчанию{словарь}, опционально

Словарь, сопоставляющий имена полей с соответствующими значениями по умолчанию.

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, сглаживать=False, usemask=False, asrecarray=False)[источник]#

Объединение массивов по полям.

Параметры:
seqarraysпоследовательность ndarrays

Последовательность массивов

fill_value{float}, опционально

Значение заполнения, используемое для дополнения отсутствующих данных в более коротких массивах.

сглаживать{False, True}, опционально

Сворачивать ли вложенные поля.

usemask{False, True}, опционально

Возвращать ли маскированный массив или нет.

asrecarray{False, True}, опционально

Возвращать ли recarray (MaskedRecords) или нет.

Примечания

  • Без маски пропущенное значение будет заполнено чем-то, в зависимости от соответствующего типа:

    • -1 для целых чисел

    • -1.0 для чисел с плавающей точкой

    • '-' для символов

    • '-1' для строк

    • True для логических значений

  • XXX: Я просто получил эти значения эмпирически

Примеры

>>> import numpy as np
>>> 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', '
>>> 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', '
>>> 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', '
numpy.lib.recfunctions.rec_append_fields(основание, names, данные, dtypes=None)[источник]#

Добавить новые поля в существующий массив.

Имена полей задаются с помощью names аргументы, соответствующие значения с данные аргументы. Если добавляется одно поле, names, данные и dtypes не обязаны быть списками, а просто значениями.

Параметры:
основаниемассив

Входной массив для расширения.

namesстрока, последовательность

Строка или последовательность строк, соответствующих именам новых полей.

данныемассив или последовательность массивов

Массив или последовательность массивов, хранящих поля для добавления к базе.

dtypesпоследовательность типов данных, опционально

Тип данных или последовательность типов данных. Если None, типы данных оцениваются из данные.

Возвращает:
appended_arraynp.recarray

Смотрите также

append_fields
numpy.lib.recfunctions.rec_drop_fields(основание, drop_names)[источник]#

Возвращает новый numpy.recarray с полями в drop_names удален.

numpy.lib.recfunctions.rec_join(ключ, r1, r2, jointype='inner', r1postfix='1', r2postfix='2', значения по умолчанию=None)[источник]#

Объединение массивов r1 и r2 по ключам. Альтернатива join_by, которая всегда возвращает np.recarray.

Смотрите также

join_by

эквивалентная функция

numpy.lib.recfunctions.recursive_fill_fields(входные данные, вывод)[источник]#

Заполняет поля из вывода полями из ввода, с поддержкой вложенных структур.

Параметры:
входные данныеndarray

Входной массив.

выводndarray

Выходной массив.

Примечания

  • вывод должен быть как минимум такого же размера, как входные данные

Примеры

>>> import numpy as np
>>> 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', '
numpy.lib.recfunctions.rename_fields(основание, namemapper)[источник]#

Переименовать поля из гибкого типа данных ndarray или recarray.

Поддерживаются вложенные поля.

Параметры:
основаниеndarray

Входной массив, поля которого должны быть изменены.

namemapperсловарь

Словарь, сопоставляющий старые имена полей с их новыми версиями.

Примеры

>>> import numpy as np
>>> 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', '
numpy.lib.recfunctions.repack_fields(a, выравнивать=False, recurse=False)[источник]#

Переупаковать поля структурированного массива или типа данных в памяти.

Расположение в памяти структурированных типов данных позволяет полям находиться на произвольных смещениях в байтах. Это означает, что поля могут быть разделены байтами заполнения, их смещения могут возрастать не монотонно, и они могут перекрываться.

Этот метод удаляет любые перекрытия и переупорядочивает поля в памяти, чтобы они имели возрастающие смещения в байтах, и добавляет или удаляет байты заполнения в зависимости от выравнивать опция, которая ведет себя как выравнивать опция для numpy.dtype.

Если align=False, этот метод создает «упакованное» расположение памяти, в котором каждое поле начинается с байта, на котором закончилось предыдущее поле, и любые байты заполнения удаляются.

Если align=True, этот метод создает "выровненное" расположение памяти, в котором смещение каждого поля кратно его выравниванию, а общий размер элемента кратен наибольшему выравниванию, путем добавления байтов заполнения по мере необходимости.

Параметры:
andarray или dtype

массив или dtype, для которого переупаковываются поля.

выравниватьлогический

Если true, используется «выровненная» структура памяти, в противном случае используется «упакованная» структура.

recurseлогический

Если True, также перепаковывать вложенные структуры.

Возвращает:
переупакованndarray или dtype

Копия a с переупакованными полями, или a сам, если переупаковка не была нужна.

Примеры

>>> import numpy as np
>>> 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, , align=True)
>>> dt
dtype({'names': ['f0', 'f1', 'f2'], 'formats': ['u1', '
>>> print_offsets(dt)
offsets: [0, 8, 16]
itemsize: 24
>>> packed_dt = rfn.repack_fields(dt)
>>> packed_dt
dtype([('f0', 'u1'), ('f1', '
>>> print_offsets(packed_dt)
offsets: [0, 1, 9]
itemsize: 17
numpy.lib.recfunctions.require_fields(массив, required_dtype)[источник]#

Преобразует структурированный массив в новый dtype с использованием присваивания по имени поля.

Эта функция присваивает значения из старого массива в новый по имени, поэтому значение поля в выходном массиве — это значение поля с тем же именем в исходном массиве. Это создает новый ndarray, содержащий только поля, «требуемые» required_dtype.

Если имя поля в required_dtype отсутствует во входном массиве, это поле создаётся и устанавливается в 0 в выходном массиве.

Параметры:
andarray

массив для приведения

required_dtypedtype

тип данных для выходного массива

Возвращает:
выходndarray

массив с новым dtype, со значениями полей, скопированными из полей во входном массиве с тем же именем

Примеры

>>> import numpy as np
>>> 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', '
>>> rfn.require_fields(a, [('b', 'f4'), ('newf', 'u1')])
array([(1., 0), (1., 0), (1., 0), (1., 0)],
  dtype=[('b', '
numpy.lib.recfunctions.stack_arrays(массивы, значения по умолчанию=None, usemask=True, asrecarray=False, autoconvert=False)[источник]#

Накладывает поля массивов поле за полем

Параметры:
массивымассив или последовательность

Последовательность входных массивов.

значения по умолчаниюсловарь, опционально

Словарь, сопоставляющий имена полей с соответствующими значениями по умолчанию.

usemask{True, False}, опционально

Возвращать ли MaskedArray (или MaskedRecords, если asrecarray==True) или ndarray.

asrecarray{False, True}, опционально

Возвращать ли recarray (или MaskedRecords, если usemask==True) или просто ndarray гибкого типа.

autoconvert{False, True}, опционально

Автоматически ли приводить тип поля к максимальному.

Примеры

>>> import numpy as np
>>> 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', '
numpy.lib.recfunctions.structured_to_unstructured(arr, dtype=None, copy=False, приведение типов='unsafe')[источник]#

Преобразует n-мерный структурированный массив в (n+1)-мерный неструктурированный массив.

Новый массив будет иметь новое последнее измерение, равное по размеру количеству элементов полей входного массива. Если не указано, выходной тип данных определяется по правилам продвижения типов numpy, применённым ко всем типам данных полей.

Вложенные поля, а также каждый элемент любых подмассивных полей, все считаются как отдельные элементы полей.

Параметры:
arrndarray

Структурированный массив или тип данных для преобразования. Не может содержать тип данных object.

dtypedtype, опционально

Тип данных выходного неструктурированного массива.

copybool, необязательно

Если true, всегда возвращать копию. Если false, представление возвращается, если это возможно, например, когда dtype и шаги полей подходят, а подтип массива является одним из numpy.ndarray, numpy.recarray или numpy.memmap.

Изменено в версии 1.25.0: Теперь может быть возвращено представление, если поля разделены равномерным шагом.

приведение типов{‘no’, ‘equiv’, ‘safe’, ‘same_kind’, ‘unsafe’}, опционально

См. аргумент приведения типов в numpy.ndarray.astype. Определяет, какие преобразования типов данных могут происходить.

Возвращает:
неструктурированныйndarray

Неструктурированный массив с дополнительным измерением.

Примеры

>>> import numpy as np
>>> 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', '
>>> 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, выравнивать=False, copy=False, приведение типов='unsafe')[источник]#

Преобразует n-мерный неструктурированный массив в (n-1)-мерный структурированный массив.

Последнее измерение входного массива преобразуется в структуру с количеством элементов-полей, равным размеру последнего измерения входного массива. По умолчанию все выходные поля имеют тип данных входного массива, но вместо этого может быть предоставлен структурированный тип данных вывода с равным количеством элементов-полей.

Вложенные поля, а также каждый элемент любых подмассивов полей, все учитываются в количестве элементов полей.

Параметры:
arrndarray

Неструктурированный массив или dtype для преобразования.

dtypedtype, опционально

Структурированный dtype выходного массива

namesсписок строк, опционально

Если dtype не указан, это определяет имена полей для выходного dtype, по порядку. Типы данных полей будут такими же, как у входного массива.

выравниватьлогический, необязательный

Создавать ли выровненный макет памяти.

copybool, необязательно

См. аргумент copy в numpy.ndarray.astype. Если true, всегда возвращать копию. Если false, и dtype требования выполнены, возвращается представление.

приведение типов{‘no’, ‘equiv’, ‘safe’, ‘same_kind’, ‘unsafe’}, опционально

См. аргумент приведения типов в numpy.ndarray.astype. Определяет, какие преобразования типов данных могут происходить.

Возвращает:
структурированныйndarray

Структурированный массив с меньшим количеством измерений.

Примеры

>>> import numpy as np
>>> 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', '