Объекты типов данных (dtype)
Объект типа данных (экземпляр класса numpy.dtype) описывает, как следует интерпретировать байты в фиксированном блоке памяти, соответствующем элементу массива. Он описывает следующие аспекты данных:
- Тип данных (целое число, число с плавающей точкой, объект Python и т. д.)
- Размер данных (сколько байт, например, занимает целое число)
- Порядок байтов данных (маленький порядок байт или большой порядок байт)
-
Если тип данных — это структурированный тип данных, агрегат других типов данных (например, описывающий элемент массива, состоящий из целого числа и числа с плавающей точкой),
- каковы имена «полей» структуры, по которым к ним можно обратиться,
- каков тип данных каждого поля и
- какую часть блока памяти занимает каждое поле.
- Если тип данных — это подмассив, каковы его форма и тип данных.
Для описания типа скалярных данных в NumPy существуют несколько встроенных скалярных типов для различной точности целых чисел, чисел с плавающей точкой и т. д. Элемент, извлеченный из массива, например, с помощью индексирования, будет объектом Python, тип которого — скалярный тип, связанный с типом данных массива.
Обратите внимание, что скалярные типы не являются объектами dtype, хотя их можно использовать вместо одного, когда в NumPy требуется указание типа данных.
Структурированные типы данных создаются путем создания типа данных, поле которого содержит другие типы данных. Каждое поле имеет имя, по которому к нему можно обратиться. Родительский тип данных должен быть достаточного размера, чтобы содержать все его поля; родительский тип почти всегда базируется на типе void, который допускает произвольный размер элемента.
Структурированные типы данных также могут содержать вложенные структурированные подмассивы в своих полях.
Наконец, тип данных может описывать элементы, которые сами являются массивами элементов другого типа данных. Однако эти подмассивы должны иметь фиксированный размер.
Если массив создается с помощью типа данных, описывающего подмассив, размерности подмассива добавляются к форме массива при создании массива. Подмассивы в поле структурированного типа ведут себя по-другому, см. Доступ к полям.
Подмассивы всегда имеют упорядоченную в памяти последовательность типа C.
Пример
Простой тип данных, содержащий 32-битное целое число в формате big-endian: (см. Указание и построение типов данных для получения подробностей о построении)
>>> dt = np.dtype('>i4')
>>> dt.byteorder
'>'
>>> dt.itemsize
4
>>> dt.name
'int32'
>>> dt.type is np.int32
True
Соответствующий скалярный тип массива — int32.
Пример
Структурированный тип данных, содержащий строку длиной 16 символов (в поле «name») и подмассив из двух 64-битных чисел с плавающей точкой (в поле «grades»):
>>> dt = np.dtype([('name', np.str_, 16), ('grades', np.float64, (2,))])
>>> dt['name']
dtype('<U16')
>>> dt['grades']
dtype(('<f8', (2,)))
Элементы массива этого типа данных заключены в скалярный тип массива, который также имеет два поля:
>>> x = np.array([('Sarah', (8.0, 7.0)), ('John', (6.0, 7.0))], dtype=dt)
>>> x[1]
('John', [6., 7.])
>>> x[1]['grades']
array([6., 7.])
>>> type(x[1])
<class 'numpy.void'>
>>> type(x[1]['grades'])
<class 'numpy.ndarray'>
Указание и создание типов данных
Всякий раз, когда в функции или методе NumPy требуется тип данных, можно указать объект dtype или что-либо, что может быть преобразовано в него. Такие преобразования выполняются конструктором dtype:
| Создать объект типа данных. |
Описание того, что может быть преобразовано в объект типа данных, приведено ниже:
-
dtypeобъект -
Используется как есть.
- None
-
Тип данных по умолчанию:
float64.
- Типы массивно-скалярных данных
-
Все 24 встроенных объекта объектов типа массивно-скалярных данных преобразуются в соответствующий объект типа данных. Это также верно для их подклассов.
Обратите внимание, что не вся информация о типе данных может быть предоставлена объектом типа: например, типы данных
flexibleимеют значение itemsize по умолчанию 0 и требуют явного указания размера для полезного использования.Пример
>>> dt = np.dtype(np.int32) # 32-bit integer >>> dt = np.dtype(np.complex128) # 128-bit complex floating-point number
- Обобщённые типы
-
Объекты обобщённых иерархических типов преобразуются в соответствующие объекты типов в соответствии с сопоставлениями:
Устарело начиная с версии 1.19: Это преобразование обобщённых скалярных типов устарело. Это связано с тем, что оно может быть неожиданным в контексте, таком как
arr.astype(dtype=np.floating), который преобразует массивfloat32в массивfloat64, хотяfloat32является подтипомnp.floating. - Встроенные типы Python
-
Несколько типов Python эквивалентны соответствующим массивно-скалярным данным при использовании для создания объекта
dtypeобъекта:(все остальные)
Обратите внимание, что
str_соответствует строкам Unicode с кодировкой UCS4.Пример
>>> dt = np.dtype(float) # Python-compatible floating-point number >>> dt = np.dtype(int) # Python-compatible integer >>> dt = np.dtype(object) # Python object
Примечание
Все остальные типы сопоставляются с
object_для удобства. Код должен ожидать, что такие типы могут быть сопоставлены со специфическим (новым) типом данных в будущем. - Типы с
.dtype -
Любой объект типа с атрибутом
dtype: к атрибуту будет обращаться и использоваться напрямую. Атрибут должен возвращать что-либо, что может быть преобразовано в объект типа данных.
Несколько видов строк могут быть преобразованы. Распознаваемые строки могут быть префиксованы '>' (big-endian), '<' (little-endian) или '=' (родной для оборудования, по умолчанию), чтобы указать порядок байтов.
- Строки с одним символом
-
Каждый встроенный тип данных имеет код символа (обновлённые числовые типы кодов), который его однозначно идентифицирует.
Пример
>>> dt = np.dtype('b') # byte, native byte order >>> dt = np.dtype('>H') # big-endian unsigned short >>> dt = np.dtype('<f') # little-endian single-precision float >>> dt = np.dtype('d') # double-precision floating-point number - Строки типа протокола массивов (см. Протокол интерфейса массивов)
-
Первый символ указывает тип данных, а оставшиеся символы — количество байт на элемент, за исключением Unicode, где он интерпретируется как количество символов. Размер элемента должен соответствовать существующему типу, в противном случае будет выброшено исключение. Поддерживаемые типы:
'?'логический
'b'(знаковое) байтовое
'B'беззнаковое байтовое
'i'(знаковое) целое
'u'беззнаковое целое
'f'с плавающей точкой
'c'комплексное число с плавающей точкой
'm'timedelta
'M'datetime
'O'(объекты Python)
'S','a'байты с нулевым завершением (не рекомендуется)
'U'строка Unicode
'V'необработанные данные (
void)Пример
>>> dt = np.dtype('i4') # 32-bit signed integer >>> dt = np.dtype('f8') # 64-bit floating-point number >>> dt = np.dtype('c16') # 128-bit complex floating-point number >>> dt = np.dtype('S25') # 25-length zero-terminated bytes >>> dt = np.dtype('U25') # 25-character stringПримечание о типах строк
Для обратной совместимости со старым кодом, написанным для поддержки Python 2, типы строк
Sиaпредставляют собой байты с нулевым завершением. Для строк Unicode используйтеU,numpy.str_. Для знакомых байтов, которые не нуждаются в нулевом завершении, можно использоватьbилиi1. - Строка с полями, разделёнными запятыми
-
Краткая запись для указания формата структурированного типа данных — это строка с базовыми форматами, разделёнными запятыми.
Базовый формат в данном контексте — это необязательный спецификатор формы, за которым следует строка типа протокола массивов. Скобки требуются для формы, если она имеет более одной размерности. NumPy позволяет изменять формат, так что любая строка, которая однозначно идентифицирует тип, может быть использована для указания типа данных в поле. Сгенерированные поля типа данных называются
'f0','f1', …,'f<N-1>', где N (>1) — количество базовых форматов, разделённых запятыми, в строке. Если предоставлен необязательный спецификатор формы, то тип данных соответствующего поля описывает подмассив.Пример
- поле с именем
f0, содержащее 32-битное целое число - поле с именем
f1, содержащее подмассив размером 2x3 с 64-битными числами с плавающей точкой - поле с именем
f2содержащее 32-битное число с плавающей точкой
>>> dt = np.dtype("i4, (2,3)f8, f4")- поле с именем
f0содержащее строку из 3 символов - поле с именем
f1содержащее подмассив с формой (3,) содержащий 64-битные беззнаковые целые числа - поле с именем
f2содержащее подмассив размером 3x4, содержащий строки из 10 символов
>>> dt = np.dtype("S3, 3u8, (3,4)S10") - поле с именем
- Строки типов
-
Любое имя строки типа NumPy, например:
Пример
>>> dt = np.dtype('uint32') # 32-bit unsigned integer >>> dt = np.dtype('float64') # 64-bit floating-point number
(flexible_dtype, itemsize)-
Первый аргумент должен быть объектом, который преобразуется в объект гибкого типа данных нулевого размера, второй аргумент — целое число, задающее желаемый размер элемента.
Пример
>>> dt = np.dtype((np.void, 10)) # 10-byte wide data block >>> dt = np.dtype(('U', 10)) # 10-character unicode string (fixed_dtype, shape)-
Первый аргумент — любой объект, который может быть преобразован в объект фиксированного размера типа данных. Второй аргумент — желаемая форма этого типа. Если параметр формы равен 1, то объект типа данных эквивалентен фиксированному типу данных. Это поведение устарело с NumPy 1.17 и в будущем будет вызывать ошибку. Если форма является кортежем, то новый тип данных определяет подмассив заданной формы.
Пример
>>> dt = np.dtype((np.int32, (2,2))) # 2 x 2 integer sub-array >>> dt = np.dtype(('i4, (2,3)f8, f4', (2,3))) # 2 x 3 structured sub-array
[(field_name, field_dtype, field_shape), ...]-
obj должен быть списком полей, где каждое поле описывается кортежем длиной 2 или 3. (Эквивалентно элементу
descrв атрибуте__array_interface__.)Первый элемент, имя_поля, — имя поля (если это
'', то назначается стандартное имя поля,'f#'). Имя поля также может быть кортежем из двух строк, где первая строка — это «заголовок» (любая строка или строка Unicode) или метаданные для поля, которые могут быть любым объектом, а вторая строка — «имя», которое должно быть допустимым идентификатором Python.Второй элемент, тип_данных_поля, может быть чем угодно, что можно интерпретировать как тип данных.
Необязательный третий элемент форма_поля содержит форму, если это поле представляет собой массив типа данных во втором элементе. Обратите внимание, что кортеж из 3 элементов с третьим аргументом, равным 1, эквивалентен кортежу из 2 элементов.
Этот стиль не принимает выравнивание в конструкторе
dtype, так как предполагается, что вся память учтена описанием интерфейса массива.Пример
Тип данных с полями
big(целое 32-битное большого порядка) иlittle(целое 32-битное малого порядка):>>> dt = np.dtype([('big', '>i4'), ('little', '<i4')])Тип данных с полями
R,G,B,A, каждое из которых представляет собой беззнаковое 8-битное целое число:>>> dt = np.dtype([('R','u1'), ('G','u1'), ('B','u1'), ('A','u1')])
{'names': ..., 'formats': ..., 'offsets': ..., 'titles': ..., 'itemsize': ...}-
Этот стиль имеет два обязательных и три необязательных ключа. Ключи имена и форматы обязательны. Их значения — списки одинаковой длины с именами полей и форматами полей. Имена полей должны быть строками, а форматы полей могут быть любым объектом, принимаемым конструктором
dtype.При предоставлении необязательных ключей смещения и заголовки их значения должны быть списками той же длины, что и списки имена и форматы. Значение смещения — список байтовых смещений (ограниченных
ctypes.c_int) для каждого поля, а значение заголовки — список заголовков для каждого поля (Noneиспользуется, если заголовок для поля не требуется). Заголовки могут быть любыми объектами, но при использовании объектаstrв словарь полей добавляется ещё одна запись с ключом-заголовком и ссылкой на тот же кортеж поля, который будет содержать заголовок как дополнительный член кортежа.Ключ itemsize позволяет установить общий размер типа данных и должен быть целым числом, достаточно большим, чтобы все поля находились внутри типа данных. Если конструктируемый тип данных выровнен, itemsize также должен быть кратным выравниванию структуры. Общий размер типа данных itemsize ограничен
ctypes.c_int.Пример
Тип данных с полями
r,g,b,a, каждое из которых является 8-битным беззнаковым целым числом:>>> dt = np.dtype({'names': ['r','g','b','a'], ... 'formats': [np.uint8, np.uint8, np.uint8, np.uint8]})Тип данных с полями
rиb(с заданными заголовками), оба являющиеся 8-битными беззнаковыми целыми числами, первое — в байтовой позиции 0 от начала поля, а второе — в позиции 2:>>> dt = np.dtype({'names': ['r','b'], 'formats': ['u1', 'u1'], ... 'offsets': [0, 2], ... 'titles': ['Red pixel', 'Blue pixel']}) {'field1': ..., 'field2': ..., ...}-
Это использование не рекомендуется, так как оно неоднозначно с другим методом построения на основе словаря. Если у вас есть поле с именем «имена» и поле с именем «форматы», возникнет конфликт.
Этот стиль позволяет передавать атрибут
fieldsобъекта типа данных.obj должен содержать строковые или строковые ключи Unicode, которые ссылаются на
(data-type, offset)или(data-type, offset, title)кортежи.Пример
Тип данных, содержащий поле
col1(строка из 10 символов в байтовой позиции 0),col2(32-битное число с плавающей точкой в байтовой позиции 10) иcol3(целые числа в байтовой позиции 14):>>> dt = np.dtype({'col1': ('U10', 0), 'col2': (np.float32, 10), ... 'col3': (int, 14)}) (base_dtype, new_dtype)-
В NumPy 1.7 и более поздних версиях эта форма позволяет
base_dtypeинтерпретироваться как структурированный тип данных. Массивы, созданные с этим типом данных, будут иметь основной типbase_dtype, но будут иметь поля и флаги, взятые изnew_dtype. Это полезно для создания пользовательских структурированных типов данных, как в массивах записей.Эта форма также позволяет указать структурированные типы данных с перекрывающимися полями, действуя как тип «объединение» в C. Однако это использование не рекомендуется, и предпочтительнее механизм объединения.
Оба аргумента должны быть преобразуемы в объекты типа данных с тем же общим размером.
Пример
32-битное целое число, первые два байта которого интерпретируются как целое число через поле
real, а последующие два байта — через полеimag.>>> dt = np.dtype((np.int32,{'real':(np.int16, 0),'imag':(np.int16, 2)}))32-битное целое число, которое интерпретируется как состоящее из подмассива формы
(4,), содержащего 8-битные целые числа:>>> dt = np.dtype((np.int32, (np.int8, 4)))
32-битное целое число, содержащее поля
r,g,b,a, которые интерпретируют 4 байта в целом числе как четыре беззнаковых целых числа:>>> dt = np.dtype(('i4', [('r','u1'),('g','u1'),('b','u1'),('a','u1')]))
Проверка типа данных
При проверке на конкретный тип данных используйте операцию сравнения ==.
Пример
>>> a = np.array([1, 2], dtype=np.float32) >>> a.dtype == np.float32 True
В отличие от типов Python, сравнение с использованием is не следует использовать.
Во-первых, NumPy обрабатывает спецификации типов данных (все, что можно передать конструктору dtype) как эквивалентные самому объекту типа данных. Это эквивалентность можно обработать только через ==, а не через is.
Пример
Объект dtype равен всем спецификациям типа данных, которые эквивалентны ему.
>>> a = np.array([1, 2], dtype=float) >>> a.dtype == np.dtype(np.float64) True >>> a.dtype == np.float64 True >>> a.dtype == float True >>> a.dtype == "float64" True >>> a.dtype == "d" True
Во-вторых, нет гарантии, что объекты типов данных являются синглтонами.
Пример
Не используйте is, так как объекты типов данных могут или не могут быть синглтонами.
>>> np.dtype(float) is np.dtype(float)
True
>>> np.dtype([('a', float)]) is np.dtype([('a', float)])
False
dtype
Описания типов данных NumPy являются экземплярами класса dtype.
Атрибуты
Тип данных описывается следующими атрибутами класса dtype:
Символьный код (один из 'biufcmMOSUV'), определяющий общий тип данных. | |
Уникальный символьный код для каждого из 21 встроенного типа. | |
Уникальное число для каждого из 21 встроенного типа. | |
Строка типа массива-протокола для данного объекта типа данных. |
Размер данных описывается следующим образом:
Имя ширины в битах для этого типа данных. | |
Размер элемента для этого объекта типа данных. |
Порядок байтов данных:
Символ, указывающий порядок байтов для этого объекта типа данных. |
Информация о подтипах в структурированном типе данных:
Словарь именованных полей, определенных для этого типа данных, или | |
Отсортированный список имен полей или |
Для типов данных, описывающих подмассивы:
Кортеж | |
Кортеж формы подмассива, если этот тип данных описывает подмассив, и |
Атрибуты, предоставляющие дополнительную информацию:
Логическое значение, указывающее, содержит ли этот dtype какие-либо объекты со ссылочным подсчётом в любых полях или подтипах. | |
Флаги в формате битов, описывающие, как следует интерпретировать этот тип данных. | |
Целое число, указывающее, как этот dtype относится к встроенным dtype. | |
Логическое значение, указывающее, соответствует ли порядок байтов этого dtype порядку байтов платформы. | |
| |
Требуемое выравнивание (байты) этого типа данных в соответствии с компилятором. | |
Возвращает dtype для базового элемента подмассивов, независимо от их размерности или формы. |
Метаданные, добавленные пользователем:
Либо |
Методы
Типы данных имеют следующий метод для изменения порядка байтов:
| Возвращает новый dtype с другим порядком байтов. |
Следующие методы реализуют протокол сериализации:
Помощник для сериализации. | |
Утилитарный метод для типизации:
| Возвращает параметризированный оболочку вокруг типа |
Операции сравнения:
| Возвращает self>=value. |
| Возвращает self>value. |
| Возвращает self<=value. |
| Возвращает self<value. |
© 2005–2024 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/2.0/reference/arrays.dtypes.html