Объекты типа данных (dtype)#

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

  1. Тип данных (целое число, число с плавающей точкой, объект Python и т.д.)

  2. Размер данных (сколько байт в например, целое число)

  3. Порядок байтов данных (little-endian или big-endian)

  4. Если тип данных структурированный тип данных, агрегат других типов данных, (например,, описывающий элемент массива, состоящий из целого числа и числа с плавающей запятой),

    1. какие имена у "поля” структуры, с помощью которой они могут быть доступен,

    2. какой тип данных у каждого field, и

    3. какую часть блока памяти занимает каждое поле.

  5. Если тип данных является подмассивом, какова его форма и тип данных.

Для описания типа скалярных данных существует несколько встроенные скалярные типы в 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 конструктор:

dtype(dtype[, align, copy])

--

Что может быть преобразовано в объект типа данных, описано ниже:

dtype object

Используется как есть.

None

Тип данных по умолчанию: float64.

Типы скаляров массива

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

int

int_

bool

bool_

float

float64

complex

complex128

bytes

bytes_

str

str_

memoryview

void

(все остальные)

object_

Обратите внимание, что 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 атрибуты:

dtype.type

dtype.kind

Символьный код (один из 'biufcmMOSTUV'), идентифицирующий общий тип данных.

dtype.char

Уникальный символьный код для каждого из 21 встроенного типа.

dtype.num

Уникальный номер для каждого из 21 встроенного типа.

dtype.str

Типовая строка протокола массива для этого объекта типа данных.

Размер данных, в свою очередь, описывается:

dtype.name

Имя битовой ширины для этого типа данных.

dtype.itemsize

Размер элемента этого объекта типа данных.

Порядок байтов этих данных:

dtype.byteorder

Символ, указывающий порядок байтов этого объекта типа данных.

Информация о подтипах данных в структурированный тип данных:

dtype.fields

Словарь именованных полей, определённых для этого типа данных, или None.

dtype.names

Упорядоченный список имён полей, или None если полей нет.

Для типов данных, описывающих подмассивы:

dtype.subdtype

Кортеж (item_dtype, shape) если это dtype описывает подмассив, иначе None.

dtype.shape

Кортеж формы подмассива, если этот тип данных описывает подмассив, и () в противном случае.

Атрибуты, предоставляющие дополнительную информацию:

dtype.hasobject

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

dtype.flags

Битовые флаги, описывающие, как следует интерпретировать этот тип данных.

dtype.isbuiltin

Целое число, указывающее, как этот dtype относится к встроенным dtypes.

dtype.isnative

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

dtype.descr

__array_interface__ описание типа данных.

dtype.alignment

Требуемое выравнивание (в байтах) этого типа данных согласно компилятору.

dtype.base

Возвращает тип данных для базового элемента подмассивов, независимо от их размерности или формы.

Метаданные, добавленные пользователем:

dtype.metadata

Либо None или доступный только для чтения словарь метаданных (mappingproxy).

Методы#

Типы данных имеют следующий метод для изменения порядка байтов:

dtype.newbyteorder([new_order])

Возвращает новый тип данных с другим порядком байтов.

Следующие методы реализуют протокол pickle:

dtype.__reduce__

Вспомогательная функция для pickle.

dtype.__setstate__

Вспомогательный метод для типизации:

dtype.__class_getitem__(item, /)

Возвращает параметризованную обертку вокруг dtype тип.

Операции сравнения:

dtype.__ge__(value, /)

Возвращает self>=value.

dtype.__gt__(value, /)

Возвращает self>value.

dtype.__le__(value, /)

Возвращает self<=value.

dtype.__lt__(value, /)

Возвращает self