Объекты типа данных (dtype)#
Объект типа данных (экземпляр numpy.dtype класс)
описывает, как следует интерпретировать байты в блоке памяти фиксированного размера,
соответствующем элементу массива. Он описывает
следующие аспекты данных:
Тип данных (целое число, число с плавающей точкой, объект Python и т.д.)
Размер данных (сколько байт в например, целое число)
Порядок байтов данных (little-endian или big-endian)
Если тип данных структурированный тип данных, агрегат других типов данных, (например,, описывающий элемент массива, состоящий из целого числа и числа с плавающей запятой),
Если тип данных является подмассивом, какова его форма и тип данных.
Для описания типа скалярных данных существует несколько встроенные скалярные типы в NumPy для различной точности целых чисел, чисел с плавающей запятой, и т.д.. Элемент, извлеченный из массива, например,, путём индексирования, будет объектом Python, тип которого является скалярным типом, связанным с типом данных массива.
Обратите внимание, что скалярные типы не dtype объекты, хотя они могут использоваться вместо них всякий раз, когда в NumPy требуется спецификация типа данных.
Структурированные типы данных формируются путем создания типа данных, чей
field содержать другие типы данных. Каждое поле имеет имя, по которому оно может быть доступен. Родительский тип данных
должен быть достаточно большим, чтобы содержать все его поля;
родитель почти всегда основан на void тип, который позволяет произвольный размер элемента. Структурированные типы данных также могут содержать вложенные структурированные подмассивы в своих полях.
Наконец, тип данных может описывать элементы, которые сами являются массивами элементов другого типа данных. Однако эти подмассивы должны иметь фиксированный размер.
Если массив создаётся с использованием типа данных, описывающего подмассив, размерности подмассива добавляются к форме массива при его создании. Подмассивы в поле структурированного типа ведут себя иначе, см. Доступ к полю.
Подмассивы всегда имеют C-последовательный макет памяти.
Пример
Простой тип данных, содержащий 32-битное целое число в формате big-endian: (см. Задание и построение типов данных для подробностей о конструкции)
>>> import numpy as np
>>> dt = np.dtype('>i4')
>>> dt.byteorder
'>'
>>> dt.itemsize
4
>>> dt.name
'int32'
>>> dt.type is np.int32
True
Соответствующий скалярный тип массива: int32.
Пример
Структурированный тип данных, содержащий 16-символьную строку (в поле 'name') и подмассив из двух 64-битных чисел с плавающей запятой (в поле 'grades'):
>>> import numpy as np>>> dt = np.dtype([('name', np.str_, 16), ('grades', np.float64, (2,))]) >>> dt['name'] dtype('>>> dt['grades'] dtype(('
Элементы массива этого типа данных обёрнуты в массив скаляр тип, который также имеет два поля:
>>> import numpy as np
>>> 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])
>>> type(x[1]['grades'])
Задание и построение типов данных#
Всякий раз, когда в функции или методе NumPy требуется тип данных, либо dtype объект или что-то, что может быть преобразовано в него, может быть предоставлено. Такие преобразования выполняются с помощью dtype
конструктор:
|
-- |
Что может быть преобразовано в объект типа данных, описано ниже:
- Типы скаляров массива
24 встроенных объекты типов скаляров массива все преобразуются в связанный объект типа данных. Это верно и для их подклассов.
Обратите внимание, что не вся информация о типе данных может быть предоставлена с помощью объекта типа: например,
flexibleтипы данных имеют значение по умолчанию itemsize равным 0 и требуют явно заданного размера, чтобы быть полезными.Пример
>>> import numpy as np
>>> 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объект:Тип Python
Тип NumPy
(все остальные)
Обратите внимание, что
str_соответствует строкам Unicode, закодированным в UCS4.Пример
>>> import numpy as np
>>> 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 Любой объект типа с
dtypeатрибут: Атрибут будет доступен и использован напрямую. Атрибут должен возвращать что-то, что можно преобразовать в объект dtype.
Несколько типов строк могут быть преобразованы. Распознаваемые строки могут быть
с префиксом '>' (big-endian), '<'
(little-endian), или '=' (аппаратно-нативный, по умолчанию), чтобы указать порядок байтов.
- Однобуквенные строки
Каждый встроенный тип данных имеет символьный код (обновлённые числовые коды типов), который однозначно его идентифицирует.
Пример
>>> import numpy as np
>>> dt = np.dtype('b') # byte, native byte order >>> dt = np.dtype('>H') # big-endian unsigned short >>> dt = np.dtype('
) # little-endian single-precision float >>> dt = np.dtype('d') # double-precision floating-point number - Строки типа протокола массива (см. Протокол интерфейса массива)
Первый символ указывает тип данных, а остальные символы указывают количество байт на элемент, за исключением Unicode, где он интерпретируется как количество символов, и за исключением
b1который представляет логическое значение. Размер элемента должен соответствовать существующему типу, иначе будет вызвана ошибка. Поддерживаемые виды:'?','b1'логический
'b'(знаковый) байт
'B'беззнаковый байт
'i'(знаковое) целое число
'u'беззнаковое целое число
'f'с плавающей точкой
'c'комплексное число с плавающей точкой
'm'timedelta
'M'datetime
'O'(Python) объекты
'S','a'нуль-терминированные байты (не рекомендуется)
'U'Строка Unicode
'V'сырые данные (
void)Пример
>>> import numpy as np
>>> 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) — количество базовых форматов, разделенных запятыми, в строке. Если указан необязательный спецификатор формы, то тип данных для соответствующего поля описывает подмассив.' Пример
поле с именем
f0содержащий 32-битное целое числополе с именем
f1содержащий подмассив 2 x 3 чисел с плавающей запятой 64-битной точностиполе с именем
f2содержащий 32-битное число с плавающей точкой>>> import numpy as np >>> dt = np.dtype("i4, (2,3)f8, f4")
поле с именем
f0содержащий строку из 3 символовполе с именем
f1содержащий подмассив формы (3,) с 64-битными беззнаковыми целыми числамиполе с именем
f2содержащий подмассив размером 3 x 4 содержащий строки длиной 10 символов>>> import numpy as np >>> dt = np.dtype("S3, 3u8, (3,4)S10")
- Строки типа
Любое строковое имя типа данных NumPy, например:
Пример
>>> import numpy as np
>>> dt = np.dtype('uint32') # 32-bit unsigned integer >>> dt = np.dtype('float64') # 64-bit floating-point number
(flexible_dtype, itemsize)Первый аргумент должен быть объектом, преобразуемым в гибкий объект типа данных нулевого размера, второй аргумент — целое число, задающее желаемый размер элемента.
Пример
>>> import numpy as np
>>> dt = np.dtype((np.void, 10)) # 10-byte wide data block >>> dt = np.dtype(('U', 10)) # 10-character unicode string
(fixed_dtype, shape)Первый аргумент - любой объект, который может быть преобразован в объект типа данных фиксированного размера. Второй аргумент - желаемая форма этого типа. Если параметр shape равен 1, то объект типа данных ранее был эквивалентен фиксированному dtype. Это поведение устарело с NumPy 1.17 и вызовет ошибку в будущем. Если shape является кортежем, то новый dtype определяет подмассив заданной формы.
Пример
>>> import numpy as np
>>> 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__атрибут.)Первый элемент, field_name, это имя поля (если это
''затем стандартное имя поля,'f#', присваивается). Имя поля также может быть кортежем из двух строк, где первая строка является либо "заголовком" (который может быть любой строкой или строкой Unicode), либо метаданными для поля, которые могут быть любым объектом, а вторая строка — "именем", которое должно быть допустимым идентификатором Python.Второй элемент, field_dtype, может быть чем угодно, что можно интерпретировать как тип данных.
Необязательный третий элемент field_shape содержит форму, если это поле представляет массив типа данных во втором элементе. Обратите внимание, что кортеж из трех элементов с третьим аргументом, равным 1, эквивалентен кортежу из двух элементов.
Этот стиль не принимает выравнивать в
dtypeконструктор, так как предполагается, что вся память учтена в описании интерфейса массива.Пример
Тип данных с полями
big(32-битное целое число big-endian) иlittle(32-битное целое число с обратным порядком байтов):>>> import numpy as np
>>> dt = np.dtype([('big', '>i4'), ('little', '
)]) Тип данных с полями
R,G,B,A, каждый из которых является беззнаковым 8-битным целым числом:>>> dt = np.dtype([('R','u1'), ('G','u1'), ('B','u1'), ('A','u1')])
{'names': ..., 'formats': ..., 'offsets': ..., 'titles': ..., 'itemsize': ...}Этот стиль имеет два обязательных и три необязательных ключа. names и форматы ключи обязательны. Их соответствующие значения – это списки одинаковой длины с именами полей и форматами полей. Имена полей должны быть строками, а форматы полей могут быть любыми объектами, принимаемыми
dtypeконструктор.Когда необязательные ключи смещения и заголовки предоставлены, их значения должны быть списками той же длины, что и names и форматы списки. The смещения значение представляет собой список смещений в байтах (ограничено
ctypes.c_int) для каждого поля, в то время как заголовки значение представляет собой список заголовков для каждого поля (Noneможет использоваться, если для этого поля не требуется заголовок). Параметр заголовки может быть любым объектом, но когдаstrобъект добавит еще одну запись в словарь fields с ключом, равным заголовку, и ссылкой на тот же кортеж field, который будет содержать заголовок как дополнительный элемент кортежа.The itemsize key позволяет установить общий размер dtype и должен быть целым числом, достаточно большим, чтобы все поля находились в пределах dtype. Если создаваемый dtype выровнен, то itemsize также должно быть кратно выравниванию структуры. Общий dtype itemsize ограничен
ctypes.c_int.Пример
Тип данных с полями
r,g,b,a, каждый из которых является 8-битным беззнаковым целым числом:>>> import numpy as np
>>> 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': ..., ...}Такое использование не рекомендуется, поскольку оно неоднозначно с другим методом построения на основе словаря. Если у вас есть поле с именем 'names' и поле с именем 'formats', возникнет конфликт.
Этот стиль позволяет передавать
fieldsатрибут объекта типа данных.obj должен содержать строковые или юникодные ключи, ссылающиеся на
(data-type, offset)или(data-type, offset, title)tuples.Пример
Тип данных, содержащий поле
col1(10-символьная строка на позиции байта 0),col2(32-битное число с плавающей точкой в позиции байта 10), иcol3(целые числа в позиции байта 14):>>> import numpy as np
>>> dt = np.dtype({'col1': ('U10', 0), 'col2': (np.float32, 10), ... 'col3': (int, 14)})
(base_dtype, new_dtype)В NumPy 1.7 и более поздних версиях эта форма позволяет base_dtype интерпретироваться как структурированный dtype. Массивы, созданные с этим dtype, будут иметь базовый dtype base_dtype но будет иметь поля и флаги, взятые из new_dtype. Это полезно для создания пользовательских структурированных типов данных, как сделано в записывающие массивы.
Эта форма также позволяет задавать структурированные типы данных с перекрывающимися полями, работающие как тип 'union' в C. Однако такое использование не рекомендуется, и предпочтительнее механизм union.
Оба аргумента должны быть преобразуемы в объекты типа данных с одинаковым общим размером.
Пример
32-битное целое число, первые два байта которого интерпретируются как целое число через поле
real, и следующие два байта через полеimag.>>> import numpy as np
>>> 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')]))
Проверка типа данных#
При проверке конкретного типа данных используйте == сравнение.
Пример
>>> import numpy as np
>>> a = np.array([1, 2], dtype=np.float32)
>>> a.dtype == np.float32
True
В отличие от типов Python, сравнение с использованием is не следует использовать.
Во-первых, NumPy обрабатывает спецификации типов данных (всё, что можно передать в dtype конструктор) как эквивалент самому объекту типа данных.
Эта эквивалентность может быть обработана только через ==, не через is.
Пример
A dtype объект равен всем спецификациям типа данных, которые
эквивалентны ему.
>>> import numpy as np
>>> 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 поскольку объекты типов данных могут быть или не быть синглтонами.
>>> import numpy as np
>>> np.dtype(float) is np.dtype(float)
True
>>> np.dtype([('a', float)]) is np.dtype([('a', float)])
False
dtype#
Описания типов данных NumPy являются экземплярами dtype класс.
Атрибуты#
Тип данных описывается следующим dtype атрибуты:
Символьный код (один из 'biufcmMOSTUV'), идентифицирующий общий тип данных. |
|
Уникальный символьный код для каждого из 21 встроенного типа. |
|
Уникальный номер для каждого из 21 встроенного типа. |
|
Типовая строка протокола массива для этого объекта типа данных. |
Размер данных, в свою очередь, описывается:
Имя битовой ширины для этого типа данных. |
|
Размер элемента этого объекта типа данных. |
Порядок байтов этих данных:
Символ, указывающий порядок байтов этого объекта типа данных. |
Информация о подтипах данных в структурированный тип данных:
Словарь именованных полей, определённых для этого типа данных, или |
|
Упорядоченный список имён полей, или |
Для типов данных, описывающих подмассивы:
Кортеж |
|
Кортеж формы подмассива, если этот тип данных описывает подмассив, и |
Атрибуты, предоставляющие дополнительную информацию:
Булево значение, указывающее, содержит ли этот dtype какие-либо объекты с подсчетом ссылок в любых полях или под-dtype. |
|
Битовые флаги, описывающие, как следует интерпретировать этот тип данных. |
|
Целое число, указывающее, как этот dtype относится к встроенным dtypes. |
|
Логическое значение, указывающее, является ли порядок байтов этого dtype родным для платформы. |
|
__array_interface__ описание типа данных. |
|
Требуемое выравнивание (в байтах) этого типа данных согласно компилятору. |
|
Возвращает тип данных для базового элемента подмассивов, независимо от их размерности или формы. |
Метаданные, добавленные пользователем:
Либо |
Методы#
Типы данных имеют следующий метод для изменения порядка байтов:
|
Возвращает новый тип данных с другим порядком байтов. |
Следующие методы реализуют протокол pickle:
Вспомогательная функция для pickle. |
|
Вспомогательный метод для типизации:
|
Возвращает параметризованную обертку вокруг |
Операции сравнения:
|
Возвращает self>=value. |
|
Возвращает self>value. |
|
Возвращает self<=value. |
|
Возвращает self |