Структурированные массивы
Введение
Структурированные массивы — это 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]
('Fido', 3, 27.0)
Вы можете получить доступ к отдельным полям структурированного массива и изменять их, используя имя поля в качестве индекса:
>>> x['age']
array([9, 3], dtype=int32)
>>> x['age'] = 5
>>> x
array([('Rex', 5, 81.), ('Fido', 5, 27.)],
dtype=[('name', 'U10'), ('age', '<i4'), ('weight', '<f4')])
Структурированные типы данных предназначены для имитации структур в языке C и имеют похожую организацию в памяти. Они предназначены для взаимодействия с кодом C и для низкоуровневой обработки структурированных буферов, например, для интерпретации двоичных блоков. В этих целях они поддерживают специализированные функции, такие как подмассивы, вложенные типы данных и объединения, и позволяют контролировать структуру памяти структуры.
Пользователи, желающие работать с табличными данными, такими как данные в файлах csv, могут найти более подходящие проекты pydata, такие как xarray, pandas или DataArray. Они предоставляют высокоуровневый интерфейс для анализа табличных данных и оптимизированы для этого использования. Например, структура данных C-структурного типа в структурированных массивах numpy может приводить к плохой производительности кэширования по сравнению с ними.
Структурированные типы данных
Структурированный тип данных можно рассматривать как последовательность байтов определённой длины (размер элемента структуры — itemsize), интерпретируемая как набор полей. Каждое поле имеет имя, тип данных и смещение в байтах относительно начала структуры. Тип данных поля может быть любым типом данных numpy, включая другие структурированные типы данных, а также тип данных подмассива, который ведет себя как ndarray заданной формы. Смещения полей произвольны, и поля могут даже перекрываться. Эти смещения обычно определяются автоматически numpy, но их также можно указать.
Создание структурированных типов данных
Структурированные типы данных могут быть созданы с помощью функции numpy.dtype. Существует 4 альтернативных формы спецификации, которые различаются гибкостью и краткостью. Подробнее о них описано на странице справки по Объектам типов данных, и кратко они таковы:
-
Список кортежей, по одному кортежу на каждое поле
Каждый кортеж имеет вид
(fieldname, datatype, shape)где форма необязательна.fieldname— это строка (или кортеж, если используются заголовки, см. Заголовки полей ниже),datatypeможет быть любым объектом, преобразуемым в тип данных, иshape— это кортеж целых чисел, определяющий форму подмассива.>>> np.dtype([('x', 'f4'), ('y', np.float32), ('z', 'f4', (2, 2))]) dtype([('x', '<f4'), ('y', '<f4'), ('z', '<f4', (2, 2))])Если
fieldname— это пустая строка'', полю будет присвоено имя по умолчанию видаf#, где#— это целочисленный индекс поля, считающийся слева от 0:>>> np.dtype([('x', 'f4'), ('', 'i4'), ('z', 'i8')]) dtype([('x', '<f4'), ('f1', '<i4'), ('z', '<i8')])Смещения в байтах полей в структуре и общий размер структуры в байтах определяются автоматически.
-
Строка со спецификациями типов данных, разделённых запятыми
В этой сокращённой записи можно использовать любые строковые спецификации типов данных, разделённые запятыми. Размер структуры в байтах и смещения в байтах полей определяются автоматически, а имена полей получают значения по умолчанию
f0,f1, и т.д.>>> np.dtype('i8, f4, S3') dtype([('f0', '<i8'), ('f1', '<f4'), ('f2', 'S3')]) >>> np.dtype('3int8, float32, (2, 3)float64') dtype([('f0', 'i1', (3,)), ('f1', '<f4'), ('f2', '<f8', (2, 3))]) -
Словарь с параметрами массивов полей
Это самая гибкая форма спецификации, поскольку она позволяет контролировать смещения в байтах полей и размер структуры в байтах.
Словарь содержит два обязательных ключа, ‘names’ и ‘formats’, и четыре необязательных ключа, ‘offsets’, ‘itemsize’, ‘aligned’ и ‘titles’. Значения для ‘names’ и ‘formats’ должны соответственно быть списком имён полей и списком спецификаций типов данных такой же длины. Необязательное значение ‘offsets’ должно быть списком целочисленных смещений в байтах, по одному на каждое поле в структуре. Если ‘offsets’ не указано, смещения определяются автоматически. Необязательное значение ‘itemsize’ должно быть целым числом, описывающим общий размер в байтах типа данных, который должен быть достаточно большим, чтобы содержать все поля.
>>> 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не могут перекрываться с другими полями, из-за риска перезаписи внутреннего указателя объекта и последующего его обращения.Необязательное значение ‘aligned’ может быть установлено в
Trueдля того, чтобы вычисление смещений использовало выровненные смещения (см. Автоматическое вычисление смещений в байтах и выравнивание), как будто аргумент ключевого слова ‘align’ функцииnumpy.dtypeбыл установлен в True.Необязательное значение ‘titles’ должно быть списком названий такой же длины, как ‘names’, см. Заголовки полей ниже.
-
Словарь с именами полей
Использование этой формы спецификации не рекомендуется, но здесь она документирована, потому что старый код numpy может её использовать. Ключи словаря — имена полей, а значения — кортежи, определяющие тип и смещение:
>>> np.dtype({'col1': ('i1', 0), 'col2': ('f4', 1)}) dtype([('col1', 'i1'), ('col2', '<f4')])Эта форма не рекомендуется, потому что словари Python не сохраняют порядок в версиях Python до Python 3.6, а порядок полей в структурированном типе данных имеет значение. Заголовки полей могут быть указаны с помощью 3-кортежа, см. ниже.
Работа со структурированными типами данных и вывод
Список имён полей структурированного типа данных можно найти в атрибуте names объекта типа данных:
>>> d = np.dtype([('x', 'i8'), ('y', 'f4')])
>>> d.names
('x', 'y')
Имена полей можно изменить, присвоив значения атрибуту names с использованием последовательности строк той же длины.
Объект типа данных также имеет атрибут, подобный словарю, fields, ключи которого — имена полей (и заголовки полей, см. ниже), а значения — кортежи, содержащие тип данных и смещение в байтах каждого поля.
>>> d.fields
mappingproxy({'x': (dtype('int64'), 0), 'y': (dtype('float32'), 8)})
И атрибуты names и fields будут равны None для несвязных массивов. Рекомендуемый способ проверки, является ли тип данных структурированным, — использовать if dt.names is not None вместо if dt.names, чтобы учесть типы данных с 0 полями.
Строковое представление структурированного типа данных показано в форме «список кортежей», если это возможно, в противном случае numpy использует более общую форму словаря.
Автоматическое вычисление смещений в байтах и выравнивание
Numpy использует один из двух методов для автоматического определения смещений в байтах полей и общего размера в байтах структурированного типа данных в зависимости от того, был ли указан align=True в качестве аргумента ключевого слова функции numpy.dtype.
По умолчанию (align=False), numpy упаковывает поля таким образом, что каждое поле начинается с байтового смещения, на котором закончилось предыдущее поле, и поля расположены непрерывно в памяти.
>>> def print_offsets(d):
... print("offsets:", [d.fields[name][1] for name in d.names])
... print("itemsize:", d.itemsize)
>>> print_offsets(np.dtype('u1, u1, i4, u1, i8, u2'))
offsets: [0, 1, 2, 6, 7, 15]
itemsize: 17
Если align=True установлено, numpy будет добавлять заполнение в структуру аналогично тому, как это делает многие компиляторы C для C-структур. Выровненные структуры могут улучшить производительность в некоторых случаях, за счёт увеличения размера типа данных. Байты заполнения вставляются между полями таким образом, что байтовое смещение каждого поля будет кратно выравниванию этого поля, которое обычно равно размеру поля в байтах для простых типов данных, см. PyArray_Descr.alignment. В структуру также будет добавлен конечный байт заполнения, таким образом, что её размер в байтах будет кратен максимальному выравниванию полей.
>>> print_offsets(np.dtype('u1, u1, i4, u1, i8, u2', align=True))
offsets: [0, 1, 4, 8, 16, 24]
itemsize: 32
Обратите внимание, что, хотя почти все современные компиляторы C по умолчанию выполняют заполнение таким образом, заполнение в C-структурах зависит от реализации компилятора C, поэтому такая организация памяти не гарантирует точного соответствия структуре в программе C. Может потребоваться работа, либо со стороны numpy, либо со стороны C, для получения точного соответствия.
Если смещения полей и размер структуры в байтах удовлетворяют условиям выравнивания, массив будет иметь установленный атрибут ALIGNED flag.
Функция для удобства numpy.lib.recfunctions.repack_fields преобразует выровненные типы данных или массивы в упакованные и наоборот. Она принимает в качестве аргумента тип данных или структурированный ndarray и возвращает копию с переупакованными полями с или без байтов заполнения.
Заголовки полей
Помимо имён полей, поля также могут иметь связанный заголовок, альтернативное имя, которое иногда используется как дополнительное описание или псевдоним для поля. Заголовок можно использовать для индексирования массива так же, как и имя поля.
Для добавления заголовков при использовании формы спецификации типа данных «список кортежей», имя поля можно указать как кортеж из двух строк вместо одной строки, которая будет соответствовать заголовку и имени поля соответственно. Например:
>>> np.dtype([(('my title', 'name'), 'f4')])
dtype([(('my title', 'name'), '<f4')])
При использовании первого варианта спецификации на основе словарей, заголовки могут быть переданы как дополнительный 'titles' ключ, как описано выше. При использовании второго (не рекомендуемого) варианта спецификации на основе словарей, заголовок можно передать, предоставив кортеж из 3 элементов (datatype, offset, title) вместо обычного кортежа из 2 элементов:
>>> np.dtype({'name': ('i4', 0, 'my title')})
dtype([(('my title', 'name'), '<i4')])
Словарь dtype.fields будет содержать заголовки в качестве ключей, если такие заголовки используются. Это означает, что поле с заголовком будет представлено дважды в словаре полей. Значения кортежа для этих полей также будут иметь третий элемент — заголовок поля. По этой причине, и потому что атрибут names сохраняет порядок полей, в то время как атрибут fields может этого не делать, рекомендуется перебирать поля типа данных с использованием атрибута names типа данных, который не будет перечислять заголовки, как в этом примере:
>>> for name in d.names:
... print(d.fields[name][:2])
(dtype('int64'), 0)
(dtype('float32'), 8)
Типы объединения
Структурированные типы данных в numpy реализованы с базовым типом numpy.void по умолчанию, но можно интерпретировать другие типы numpy как структурированные типы, используя форму спецификации типа данных (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])
Присваивание массиву с индексом из нескольких полей изменяет исходный массив:
>>> a[['a', 'c']] = (2, 3)
>>> a
array([(2, 0, 3.), (2, 0, 3.), (2, 0, 3.)],
dtype=[('a', '<i4'), ('b', '<i4'), ('c', '<f4')])
Это подчиняется правилам присваивания структурированных массивов, описанным выше. Например, это означает, что можно поменять значения двух полей с помощью соответствующих индексов из нескольких полей:
>>> a[['a', 'c']] = a[['c', 'a']]
Индексирование целым числом для получения структурированного скаляра
Индексирование одиночного элемента структурированного массива (с целочисленным индексом) возвращает структурированный скаляр:
>>> x = np.array([(1, 2., 3.)], dtype='i, f, f') >>> scalar = x[0] >>> scalar (1, 2., 3.) >>> type(scalar) <class 'numpy.void'>
В отличие от других скаляров numpy, структурированные скаляры изменяемы и действуют как представления в исходном массиве, так что изменение скаляра изменит исходный массив. Структурированные скаляры также поддерживают доступ и присваивание по имени поля:
>>> x = np.array([(1, 2), (3, 4)], dtype=[('foo', 'i8'), ('bar', 'f4')])
>>> s = x[0]
>>> s['bar'] = 100
>>> x
array([(1, 100.), (3, 4.)],
dtype=[('foo', '<i8'), ('bar', '<f4')])
Аналогично кортежам, структурированные скаляры также могут быть индексированы целым числом:
>>> scalar = np.array([(1, 2., 3.)], dtype='i, f, f')[0] >>> scalar[0] 1 >>> scalar[1] = 4
Таким образом, кортежи можно рассматривать как родственный Python эквивалент структурированных типов numpy, так же как родственные Python целые числа эквивалентны целочисленным типам numpy. Структурированные скаляры могут быть преобразованы в кортеж, вызвав ndarray.item:
>>> scalar.item(), type(scalar.item()) ((1, 4.0, 3.0), <class 'tuple'>)
Представление структурированных массивов, содержащих объекты
Чтобы предотвратить перезапись указателей объектов в полях типа numpy.object, numpy в настоящее время не разрешает представления структурированных массивов, содержащих объекты.
Сравнение структур
Если типы данных двух структурированных массивов void равны, проверка равенства массивов даст булевый массив с размерностями исходных массивов, с элементами, установленными на True там, где все поля соответствующих структур равны. Структурированные типы данных равны, если имена полей, типы данных и заголовки одинаковые, игнорируя порядок байтов, и поля в том же порядке:
>>> a = np.zeros(2, dtype=[('a', 'i4'), ('b', 'i4')])
>>> b = np.ones(2, dtype=[('a', 'i4'), ('b', 'i4')])
>>> a == b
array([False, False])
В настоящее время, если типы данных двух структурированных массивов void не эквивалентны, сравнение не выполняется, возвращая скалярное значение False. Это поведение устарело, начиная с numpy 1.10, и в будущем будет вызывать ошибку или производить поэлементное сравнение.
Операторы < и > всегда возвращают False при сравнении структурированных массивов void, и арифметические и побитовые операции не поддерживаются.
Массивы записей
В качестве дополнительной удобной функции numpy предоставляет подкласс ndarray, numpy.recarray, и связанные вспомогательные функции в модуле numpy.rec, которые позволяют обращаться к полям структурированных массивов по атрибуту вместо только по индексу. Массивы записей также используют специальный тип данных, numpy.record, который позволяет получать доступ к полям по атрибуту для структурированных скаляров, полученных из массива.
Самый простой способ создать массив записей — с помощью numpy.rec.array:
>>> recordarr = np.rec.array([(1, 2., 'Hello'), (2, 3., "World")],
... dtype=[('foo', 'i4'),('bar', 'f4'), ('baz', 'S10')])
>>> recordarr.bar
array([ 2., 3.], dtype=float32)
>>> recordarr[1:2]
rec.array([(2, 3., b'World')],
dtype=[('foo', '<i4'), ('bar', '<f4'), ('baz', 'S10')])
>>> recordarr[1:2].foo
array([2], dtype=int32)
>>> recordarr.foo[1:2]
array([2], dtype=int32)
>>> recordarr[1].baz
b'World'
numpy.rec.array может преобразовать множество аргументов в массивы записей, включая структурированные массивы:
>>> arr = np.array([(1, 2., 'Hello'), (2, 3., "World")],
... dtype=[('foo', 'i4'), ('bar', 'f4'), ('baz', 'S10')])
>>> recordarr = np.rec.array(arr)
Модуль numpy.rec предоставляет ряд дополнительных удобных функций для создания массивов записей, см. функции создания массивов записей.
Представление массива записей структурированного массива можно получить, используя соответствующий вид:
>>> arr = np.array([(1, 2., 'Hello'), (2, 3., "World")],
... dtype=[('foo', 'i4'),('bar', 'f4'), ('baz', 'a10')])
>>> recordarr = arr.view(dtype=np.dtype((np.record, arr.dtype)),
... type=np.recarray)
Для удобства, представление ndarray как типа np.recarray автоматически преобразуется в тип np.record, поэтому dtype можно опустить из представления:
>>> recordarr = arr.view(np.recarray)
>>> recordarr.dtype
dtype((numpy.record, [('foo', '<i4'), ('bar', '<f4'), ('baz', 'S10')]))
Чтобы вернуться к обычному 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)
<class 'numpy.ndarray'>
>>> type(recordarr.bar)
<class 'numpy.recarray'>
Обратите внимание, что если поле имеет такое же имя, как атрибут ndarray, то приоритет отдается атрибуту ndarray. Такие поля будут недоступны по атрибуту, но все еще будут доступны по индексу.
Функции-помощники для Recarray
Коллекция утилит для работы со структурированными массивами.
Большинство этих функций изначально были реализованы Джоном Хантером для matplotlib. Они были переписаны и расширены для удобства.
-
numpy.lib.recfunctions.append_fields(base, names, data, dtypes=None, fill_value=-1, usemask=True, asrecarray=False)[source] -
Добавить новые поля в существующий массив.
Имена полей задаются с помощью аргументов
names, соответствующие значения с аргументамиdata. Если добавляется одно поле,names,dataиdtypesне должны быть списками, а только значениями.- Parameters
-
-
basearray -
Входной массив для расширения.
-
namesstring, sequence -
Строка или последовательность строк, соответствующие именам новых полей.
-
dataarray or sequence of arrays -
Массив или последовательность массивов, хранящих поля для добавления к базовому массиву.
-
dtypessequence of datatypes, optional -
Тип данных или последовательность типов данных. Если None, типы данных оцениваются из
data. -
fill_value{float}, optional -
Значение заполнения, используемое для заполнения пропущенных данных в более коротких массивах.
-
usemask{False, True}, optional -
Нужно ли вернуть массив с масками или нет.
-
asrecarray{False, True}, optional -
Нужно ли вернуть recarray (MaskedRecords) или нет.
-
-
numpy.lib.recfunctions.apply_along_fields(func, arr)[source] -
Применение функции ‘func’ как редукции по полям структурированного массива.
Это аналогично
apply_along_axis, но обрабатывает поля структурированного массива как дополнительную ось. Все поля сначала приводятся к общему типу, следуя правилам повышения типа изnumpy.result_type, примененным к типам данных полей.- Parameters
-
-
funcfunction -
Функция для применения по размерности «поле». Эта функция должна поддерживать аргумент
axis, как np.mean, np.sum и т.д. -
arrndarray -
Структурированный массив, для которого необходимо применить func.
-
- Returns
-
-
outndarray -
Результат операции редукции
-
Примеры
>>> from numpy.lib import recfunctions as rfn >>> b = np.array([(1, 2, 5), (4, 5, 7), (7, 8 ,11), (10, 11, 12)], ... dtype=[('x', 'i4'), ('y', 'f4'), ('z', 'f8')]) >>> rfn.apply_along_fields(np.mean, b) array([ 2.66666667, 5.33333333, 8.66666667, 11. ]) >>> rfn.apply_along_fields(np.mean, b[['x', 'z']]) array([ 3. , 5.5, 9. , 11. ])
-
numpy.lib.recfunctions.assign_fields_by_name(dst, src, zero_unassigned=True)[source] -
Присваивание значений из одного структурированного массива в другой по имени поля.
Обычно в numpy >= 1.14 присваивание одного структурированного массива другому копирует поля «по позиции», что означает, что первое поле из src копируется в первое поле dst, и так далее, независимо от имени поля.
Эта функция, наоборот, копирует «по имени поля», таким образом, поля в dst присваиваются из поля с тем же именем в src. Это то, как работало присваивание структур в numpy >= 1.6 и <= 1.13.
- Parameters
-
-
dstndarray -
srcndarray -
Исходные и целевые массивы во время присваивания.
-
zero_unassignedbool, optional -
Если True, поля в dst, для которых не было соответствующего поля в src, заполняются значением 0 (ноль). Это было поведением numpy <= 1.13. Если False, эти поля не изменяются.
-
-
numpy.lib.recfunctions.drop_fields(base, drop_names, usemask=True, asrecarray=False)[source] -
Возвращает новый массив с опущенными полями в
drop_names.Вложенные поля поддерживаются.
- ..versionchanged: 1.18.0
-
drop_fieldsвозвращает массив с 0 полями, если все поля были удалены, а не возвращаетNoneкак раньше.
- Parameters
-
-
basearray -
Входной массив
-
drop_namesstring or sequence -
Строка или последовательность строк, соответствующие именам полей для удаления.
-
usemask{False, True}, optional -
Нужно ли вернуть массив с масками или нет.
-
asrecarraystring or sequence, optional -
Нужно ли вернуть recarray или mrecarray (
asrecarray=True) или обычный ndarray или массив с масками и гибким dtype. По умолчанию 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] -
Находит дубликаты в структурированном массиве вдоль заданного ключа
- Parameters
-
-
aarray-like -
Входной массив
-
key{string, None}, optional -
Имя полей, по которым нужно проверить дубликаты. Если None, поиск выполняется по записям
-
ignoremask{True, False}, optional -
Нужно ли игнорировать данные с масками или рассматривать их как дубликаты.
-
return_index{False, True}, optional -
Нужно ли возвращать индексы дублируемых значений.
-
Примеры
>>> 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] -
Возвращает словарь с полями, индексирующими списки их родительских полей.
Эта функция используется для упрощения доступа к вложенным полям в других полях.
- Parameters
-
-
adtypenp.dtype -
Входной тип данных
-
lastnameoptional -
Имя последнего обработанного поля (используется во время рекурсии).
-
parentsdictionary -
Словарь родительских полей (используется во время рекурсии).
-
Примеры
>>> 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] -
Возвращает имена полей входного типа данных в виде кортежа.
- Parameters
-
-
adtypedtype -
Входной тип данных
-
Примеры
>>> from numpy.lib import recfunctions as rfn >>> rfn.get_names(np.empty((1,), dtype=int)) Traceback (most recent call last): ... AttributeError: 'numpy.ndarray' object has no attribute 'names'>>> rfn.get_names(np.empty((1,), dtype=[('A',int), ('B', float)])) Traceback (most recent call last): ... AttributeError: 'numpy.ndarray' object has no attribute 'names' >>> adtype = np.dtype([('a', int), ('b', [('ba', int), ('bb', int)])]) >>> rfn.get_names(adtype) ('a', ('b', ('ba', 'bb')))
-
numpy.lib.recfunctions.get_names_flat(adtype)[source] -
Возвращает имена полей входного типа данных в виде кортежа. Вложенные структуры предварительно сглаживаются.
- Parameters
-
-
adtypedtype -
Входной тип данных
-
Примеры
>>> from numpy.lib import recfunctions as rfn >>> rfn.get_names_flat(np.empty((1,), dtype=int)) is None Traceback (most recent call last): ... AttributeError: 'numpy.ndarray' object has no attribute 'names' >>> rfn.get_names_flat(np.empty((1,), dtype=[('A',int), ('B', float)])) Traceback (most recent call last): ... AttributeError: 'numpy.ndarray' object has no attribute 'names' >>> adtype = np.dtype([('a', int), ('b', [('ba', int), ('bb', int)])]) >>> rfn.get_names_flat(adtype) ('a', 'b', 'ba', 'bb')
-
numpy.lib.recfunctions.join_by(key, r1, r2, jointype='inner', r1postfix='1', r2postfix='2', defaults=None, usemask=True, asrecarray=False)[source] -
Объединение массивов
r1иr2по ключуkey.Ключ должен быть строкой или последовательностью строк, соответствующих полям, используемым для объединения массива. Возникает исключение, если поле
keyне найдено в двух входных массивах. Ниr1, ниr2не должны содержать дубликатов поkey: наличие дубликатов сделает вывод довольно ненадежным. Обратите внимание, что дубликаты алгоритмом не проверяются.- Параметры
-
-
key{string, sequence} -
Строка или последовательность строк, соответствующих полям, используемым для сравнения.
-
r1, r2arrays -
Структурированные массивы.
-
jointype{‘inner’, ‘outer’, ‘leftouter’}, optional -
Если ‘inner’, возвращает элементы, общие для r1 и r2. Если ‘outer’, возвращает общие элементы, а также элементы r1, отсутствующие в r2, и элементы r2, отсутствующие в r1. Если ‘leftouter’, возвращает общие элементы и элементы r1, отсутствующие в r2.
-
r1postfixstring, optional -
Строка, добавляемая к именам полей r1, присутствующих в r2, но отсутствующих в ключе.
-
r2postfixstring, optional -
Строка, добавляемая к именам полей r2, присутствующих в r1, но отсутствующих в ключе.
-
defaults{dictionary}, optional -
Словарь, сопоставляющий имена полей с соответствующими значениями по умолчанию.
-
usemask{True, False}, optional -
Возвращать ли MaskedArray (или MaskedRecords, если
asrecarray==True) или ndarray. -
asrecarray{False, True}, optional -
Возвращать ли recarray (или MaskedRecords, если
usemask==True) или просто гибкий массив.
-
Примечания
- Выходной массив отсортирован по ключу.
- Формируется временный массив, в котором опускаются поля, не присутствующие в ключе для двух массивов, и результаты конкатенируются. Затем этот массив сортируется, и выбираются общие записи. Выходной массив формируется путем заполнения полей выбранными записями. Соответствие не сохраняется, если существуют дубликаты…
-
numpy.lib.recfunctions.merge_arrays(seqarrays, fill_value=-1, flatten=False, usemask=False, asrecarray=False)[source] -
Объединение массивов поле за полем.
- Параметры
-
-
seqarrayssequence of ndarrays -
Последовательность массивов
-
fill_value{float}, optional -
Значение заполнения, используемое для заполнения пропущенных данных в более коротких массивах.
-
flatten{False, True}, optional -
Сжимать ли вложенные поля.
-
usemask{False, True}, optional -
Возвращать ли массив с маской.
-
asrecarray{False, True}, optional -
Возвращать ли 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не должны быть списками, а просто значениями.- Параметры
-
-
basearray -
Входной массив для расширения.
-
namesstring, sequence -
Строка или последовательность строк, соответствующих именам новых полей.
-
dataarray or sequence of arrays -
Массив или последовательность массивов, хранящие поля для добавления к исходному массиву.
-
dtypessequence of datatypes, optional -
Тип данных или последовательность типов данных. Если 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] -
Переименование полей из гибкого массива numpy или recarray.
Поддерживаются вложенные поля.
- Параметры
-
-
basendarray -
Входной массив, поля которого необходимо изменить.
-
namemapperdictionary -
Словарь, сопоставляющий старые имена полей с новыми.
-
Примеры
>>> from numpy.lib import recfunctions as rfn >>> a = np.array([(1, (2, [3.0, 30.])), (4, (5, [6.0, 60.]))], ... dtype=[('a', int),('b', [('ba', float), ('bb', (float, 2))])]) >>> rfn.rename_fields(a, {'a':'A', 'bb':'BB'}) array([(1, (2., [ 3., 30.])), (4, (5., [ 6., 60.]))], dtype=[('A', '<i8'), ('b', [('ba', '<f8'), ('BB', '<f8', (2,))])])
-
numpy.lib.recfunctions.repack_fields(a, align=False, recurse=False)[source] -
Переупаковка полей структурированного массива или типа данных в памяти.
Макет памяти структурированных типов данных допускает поля с произвольными смещениями байтов. Это означает, что поля могут быть разделены байтами заполнения, их смещения могут быть немонотонно возрастающими, и они могут перекрываться.
Этот метод удаляет любые перекрытия и переупорядочивает поля в памяти так, чтобы их смещения байтов возрастали, и добавляет или удаляет байты заполнения в зависимости от параметра
align, который ведет себя так же, как параметрalignкnp.dtype.Если
align=False, этот метод создает «упакованный» макет памяти, в котором каждое поле начинается с байта, на котором закончилось предыдущее поле, и все байты заполнения удаляются.Если
align=True, этот метод создает «выровненный» макет памяти, в котором смещение каждого поля кратно его выравниванию, и общий размер элемента кратен наибольшему выравниванию, добавляя необходимые байты заполнения.- Параметры
-
-
andarray or dtype -
Массив или тип данных, для которых необходимо переупаковать поля.
-
alignboolean -
Использовать ли «выровненный» макет памяти, иначе использовать «упакованный» макет.
-
recurseboolean -
Переупаковывать ли также вложенные структуры.
-
- Возвращает
-
-
repackedndarray or 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 or sequence -
Последовательность входных массивов.
-
defaultsdictionary, optional -
Словарь, сопоставляющий имена полей с соответствующими значениями по умолчанию.
-
usemask{True, False}, optional -
Нужно ли вернуть MaskedArray (или MaskedRecords, если
asrecarray==True) или ndarray. -
asrecarray{False, True}, optional -
Нужно ли вернуть recarray (или MaskedRecords, если
usemask==True) или просто массив гибкого типа. -
autoconvert{False, True}, optional -
Автоматически ли привести тип поля к максимальному значению.
-
Примеры
>>> from numpy.lib import recfunctions as rfn >>> x = np.array([1, 2,]) >>> rfn.stack_arrays(x) is x True >>> z = np.array([('A', 1), ('B', 2)], dtype=[('A', '|S3'), ('B', float)]) >>> zz = np.array([('a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)], ... dtype=[('A', '|S3'), ('B', np.double), ('C', np.double)]) >>> test = rfn.stack_arrays((z,zz)) >>> test masked_array(data=[(b'A', 1.0, --), (b'B', 2.0, --), (b'a', 10.0, 100.0), (b'b', 20.0, 200.0), (b'c', 30.0, 300.0)], mask=[(False, False, True), (False, False, True), (False, False, False), (False, False, False), (False, False, False)], fill_value=(b'N/A', 1.e+20, 1.e+20), dtype=[('A', 'S3'), ('B', '<f8'), ('C', '<f8')])
-
numpy.lib.recfunctions.structured_to_unstructured(arr, dtype=None, copy=False, casting='unsafe')[source] -
Преобразование n-мерного структурированного массива в (n+1)-мерный неструктурированный массив.
Новый массив будет иметь новую последнюю размерность, равную числу элементов поля входного массива. Если не указано, тип данных вывода определяется по правилам повышения типа numpy, применённым ко всем типам данных полей.
Вложенные поля, а также каждый элемент любых массивов-полей, все считаются отдельными элементами поля.
- Параметры
-
-
arrndarray -
Структурированный массив или тип данных для преобразования. Не может содержать тип данных object.
-
dtypedtype, optional -
Тип данных выходного неструктурированного массива.
-
copybool, optional -
См. аргумент copy в
ndarray.astype. Если true, всегда возвращает копию. Если false, иdtypeтребования удовлетворены, возвращается представление. -
casting{‘no’, ‘equiv’, ‘safe’, ‘same_kind’, ‘unsafe’}, optional -
См. аргумент casting в
ndarray.astype. Управляет типом преобразования данных.
-
- Возвращает
-
-
unstructuredndarray -
Неструктурированный массив с одной дополнительной размерностью.
-
Примеры
>>> from numpy.lib import recfunctions as rfn >>> a = np.zeros(4, dtype=[('a', 'i4'), ('b', 'f4,u2'), ('c', 'f4', 2)]) >>> a array([(0, (0., 0), [0., 0.]), (0, (0., 0), [0., 0.]), (0, (0., 0), [0., 0.]), (0, (0., 0), [0., 0.])], dtype=[('a', '<i4'), ('b', [('f0', '<f4'), ('f1', '<u2')]), ('c', '<f4', (2,))]) >>> rfn.structured_to_unstructured(a) array([[0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.]])>>> b = np.array([(1, 2, 5), (4, 5, 7), (7, 8 ,11), (10, 11, 12)], ... dtype=[('x', 'i4'), ('y', 'f4'), ('z', 'f8')]) >>> np.mean(rfn.structured_to_unstructured(b[['x', 'z']]), axis=-1) array([ 3. , 5.5, 9. , 11. ])
-
numpy.lib.recfunctions.unstructured_to_structured(arr, dtype=None, names=None, align=False, copy=False, casting='unsafe')[source] -
Преобразование n-мерного неструктурированного массива в (n-1)-мерный структурированный массив.
Последняя размерность входного массива преобразуется в структуру с количеством элементов поля, равным размеру последней размерности входного массива. По умолчанию все поля вывода имеют тип данных входного массива, но вместо этого можно указать структурированный тип данных вывода с одинаковым количеством элементов поля.
Вложенные поля, а также каждый элемент любых массивов-полей, все учитываются в количестве элементов поля.
- Параметры
-
-
arrndarray -
Неструктурированный массив или тип данных для преобразования.
-
dtypedtype, optional -
Структурированный тип данных выходного массива
-
nameslist of strings, optional -
Если тип данных не указан, это определяет имена полей для выходного типа данных в порядке следования. Типы данных полей будут такими же, как и у входного массива.
-
alignboolean, optional -
Создавать ли выровненный макет памяти.
-
copybool, optional -
См. аргумент copy в
ndarray.astype. Если true, всегда возвращает копию. Если false, иdtypeтребования удовлетворены, возвращается представление. -
casting{‘no’, ‘equiv’, ‘safe’, ‘same_kind’, ‘unsafe’}, optional -
См. аргумент casting в
ndarray.astype. Управляет типом преобразования данных.
-
- Возвращает
-
-
structuredndarray -
Структурированный массив с меньшим количеством измерений.
-
Примеры
>>> from numpy.lib import recfunctions as rfn >>> dt = np.dtype([('a', 'i4'), ('b', 'f4,u2'), ('c', 'f4', 2)]) >>> a = np.arange(20).reshape((4,5)) >>> a array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19]]) >>> rfn.unstructured_to_structured(a, dt) array([( 0, ( 1., 2), [ 3., 4.]), ( 5, ( 6., 7), [ 8., 9.]), (10, (11., 12), [13., 14.]), (15, (16., 17), [18., 19.])], dtype=[('a', '<i4'), ('b', [('f0', '<f4'), ('f1', '<u2')]), ('c', '<f4', (2,))])
© 2005–2020 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.19/user/basics.rec.html