Объекты типов данных (dtype)
Объект типа данных (экземпляр класса numpy.dtype) описывает, как интерпретировать байты в фиксированном блоке памяти, соответствующем элементу массива. Он описывает следующие аспекты данных:
- Тип данных (целое число, число с плавающей точкой, объект Python и т.д.)
- Размер данных (сколько байтов занимает, например, целое число)
- Порядок байтов данных (малозначный или многозначный)
- Если тип данных структурированный, представляет собой агрегат других типов данных (например, описывает элемент массива, состоящий из целого числа и числа с плавающей точкой),
- какие имена «полей» структуры, используя которые их можно обращаться,
- какой тип данных у каждого поля, и
- какая часть блока памяти занимает каждое поле.
- Если тип данных является подмассивом, каковы его форма и тип данных.
Для описания типа скалярных данных в NumPy существует несколько встроенных скалярных типов с различной точностью для целых чисел, чисел с плавающей точкой и т.д. Элемент, извлеченный из массива, например, путем индексирования, будет объектом Python, тип которого является скалярным типом, связанным с типом данных массива.
Обратите внимание, что скалярные типы не являются объектами dtype, хотя их можно использовать вместо них, когда требуется указание типа данных в NumPy.
Структурированные типы данных создаются путем создания типа данных, чьи поля содержат другие типы данных. Каждое поле имеет имя, по которому к нему можно обратиться. Родительский тип данных должен иметь достаточный размер для размещения всех его полей; родительский тип почти всегда базируется на типе void, который позволяет произвольный размер элемента.
Наконец, тип данных может описывать элементы, которые сами по себе являются массивами элементов другого типа данных. Однако эти подмассивы должны иметь фиксированный размер.
Если массив создается с использованием типа данных, описывающего подмассив, размеры подмассива добавляются к форме массива при создании массива. Подмассивы в поле структурированного типа ведут себя по-другому, см. Доступ к полям.
Подмассивы всегда имеют линейную структуру памяти C.
Пример
Простой тип данных, содержащий 32-битное целое число большого порядка: (см. Указание и создание типов данных для получения подробностей о создании)
>>> 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.unicode_, 16), ('grades', np.float64, (2,))])
>>> dt['name']
dtype('|U16')
>>> dt['grades']
dtype(('float64',(2,)))
Элементы массива этого типа данных заключены в тип скаляра массива, который также имеет два поля:
>>> x = np.array([('Sarah', (8.0, 7.0)), ('John', (6.0, 7.0))], dtype=dt)
>>> x[1]
('John', [6.0, 7.0])
>>> x[1]['grades']
array([ 6., 7.])
>>> type(x[1])
<type 'numpy.void'>
>>> type(x[1]['grades'])
<type 'numpy.ndarray'>
Указание и создание типов данных
Всякий раз, когда в функции или методе NumPy требуется тип данных, можно указать объект dtype или то, что может быть преобразовано в него. Такие преобразования выполняет конструктор dtype:
dtype(obj[, align, copy]) | Создает объект типа данных. |
Описание того, что можно преобразовать в объект типа данных, приведено ниже:
dtype объект
Используется как есть.
None
Тип данных по умолчанию: float_.
Типы скаляров массивов
Все 24 встроенных объекта встроенного скалярного типа массива преобразуются в соответствующий объект типа данных. Это также верно для их подклассов.
Обратите внимание, что не вся информация о типе данных может быть предоставлена с помощью объекта типа: например, гибкие типы данных имеют значение itemsize по умолчанию 0 и требуют явно заданного размера, чтобы быть полезными.
Пример
>>> dt = np.dtype(np.int32) # 32-bit integer >>> dt = np.dtype(np.complex128) # 128-bit complex floating-point number
Общие типы
Объекты общих иерархических типов данных преобразуются в соответствующие объекты типов в соответствии с ассоциациями:
number, inexact, floating
| float |
complexfloating | cfloat |
integer, signedinteger
| int_ |
unsignedinteger | uint |
character | string |
generic, flexible
| void |
Встроенные типы Python
Несколько типов Python эквивалентны соответствующему скаляру массива, когда используются для генерации объекта dtype:
int | int_ |
bool | bool_ |
float | float_ |
complex | cfloat |
bytes | bytes_ |
str |
bytes_ (Python2) или unicode_ (Python3) |
unicode | unicode_ |
buffer | void |
| (все остальные) | object_ |
Обратите внимание, что str относится либо к нуль-терминированным байтам, либо к строкам Unicode в зависимости от версии Python. В коде, ориентированном на обе версии Python 2 и 3, следует использовать np.unicode_ в качестве типа данных для строк. См. Примечание о строковых типах.
Пример
>>> dt = np.dtype(float) # Python-compatible floating-point number >>> dt = np.dtype(int) # Python-compatible integer >>> dt = np.dtype(object) # Python object
Типы с .dtype
dtype: атрибут будет обращаться и использоваться непосредственно. Атрибут должен возвращать то, что может быть преобразовано в объект dtype. Несколько видов строк могут быть преобразованы. Признанные строки могут быть префиксом '>' (многозначный), '<' (малозначный) или '=' (родной для оборудования, по умолчанию), чтобы указать порядок байтов.
Строки из одного символа
Каждый встроенный тип данных имеет код символа (обновленные кодировки Numeric), который однозначно его идентифицирует.
Пример
>>> 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('a25') # 25-length zero-terminated bytes
>>> dt = np.dtype('U25') # 25-character string
Примечание по типам строк
Для обратной совместимости с Python 2 типы строк S и a остаются нуль-терминированными байтами, а np.string_ по-прежнему отображается как np.bytes_. Чтобы использовать фактические строки в Python 3, используйте U или np.unicode_. Для знаковых байтов, не требующих нуль-терминации, можно использовать 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("a3, 3u8, (3,4)a10")
Строки типов
Любая строка в numpy.sctypeDict.keys():
Пример
>>> 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)
Первый аргумент — любой объект, который может быть преобразован в объект фиксированного размера типа данных. Второй аргумент — желаемая форма этого типа. Если параметр shape равен 1, то объект типа данных эквивалентен фиксированному типу dtype. Если shape является кортежем, то новый dtype определяет подмассив заданной формы.
Пример
>>> dt = np.dtype((np.int32, (2,2))) # 2 x 2 integer sub-array
>>> dt = np.dtype(('U10', 1)) # 10-character string
>>> 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#'). Имя поля также может быть кортежем из двух строк, где первая строка — это либо «заголовок» (который может быть любой строкой или строкой Юникода), либо метаданные для поля, которые могут быть любым объектом, а вторая строка — «имя», которое должно быть допустимым идентификатором Python.
Второй элемент, field_dtype, может быть чем угодно, что может быть интерпретировано как тип данных.
Необязательный третий элемент field_shape содержит форму, если это поле представляет массив типа данных во втором элементе. Обратите внимание, что кортеж из 3 элементов с третьим аргументом, равным 1, эквивалентен кортежу из 2 элементов.
Этот стиль не принимает align в конструкторе 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': ...}
Этот стиль имеет два обязательных и три необязательных ключа. Ключи names и formats обязательны. Их соответствующие значения — списки одинаковой длины с именами полей и форматами полей. Имена полей должны быть строками, а форматы полей могут быть любым объектом, принятым конструктором dtype.
Когда предоставлены необязательные ключи offsets и titles, их значения должны быть списками той же длины, что и списки names и formats. Значение offsets — это список байтовых смещений (ограниченных ctypes.c_int) для каждого поля, а значение titles — это список заголовков для каждого поля (None может быть использовано, если для данного поля заголовок не требуется). Заголовки titles могут быть любыми string или unicode объектами и добавятся в словарь полей с ключом в виде заголовка, ссылающегося на тот же кортеж поля, который будет содержать заголовок как дополнительный член кортежа.
Ключ itemsize позволяет установить общий размер dtype, и он должен быть достаточно большим, чтобы все поля поместились в dtype. Если конструируемый dtype выровнен, то itemsize также должен быть кратен выравниванию структуры. Общий размер itemsize для dtype ограничен ctypes.c_int.
Пример
Тип данных с полями r, g, b, a, каждое из которых является беззнаковым 8-битным целым числом:
>>> dt = np.dtype({'names': ['r','g','b','a'],
... 'formats': [uint8, uint8, uint8, 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 должен содержать строковые или Юникод-ключи, которые ссылаются на (data-type, offset) или (data-type, offset, title) кортежи.
Пример
Тип данных, содержащий поле col1 (строка из 10 символов в байтовой позиции 0), col2 (32-битный float в байтовой позиции 10) и col3 (целые числа в байтовой позиции 14):
>>> dt = np.dtype({'col1': ('U10', 0), 'col2': (float32, 10),
'col3': (int, 14)})
(base_dtype, new_dtype)
В NumPy 1.7 и более поздних версиях эта форма позволяет base_dtype интерпретироваться как структурированный dtype. Массивы, созданные с этим dtype, будут иметь базовый dtype base_dtype, но будут иметь поля и флаги, взятые из new_dtype. Это полезно для создания пользовательских структурированных dtype, как это делается в массивах записей.
Эта форма также позволяет указать структурированные dtype с перекрывающимися полями, работая как тип «union» в 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')]))
dtype
Описания типов данных NumPy — это экземпляры класса dtype.
Атрибуты
Тип данных описывается следующими атрибутами dtype:
dtype.type | Объект типа, используемый для создания скаляра этого типа данных. |
dtype.kind | Символьный код (один из «biufcmMOSUV») для идентификации общего вида данных. |
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.flags | Битовые флаги, описывающие, как интерпретировать этот тип данных. |
dtype.isbuiltin | Целое число, указывающее, как этот тип данных относится к встроенным типам данных. |
dtype.isnative | Булево значение, указывающее, является ли порядок байтов этого типа данных родным для платформы. |
dtype.descr |
__array_interface__ описание типа данных. |
dtype.alignment | Требуемое выравнивание (байты) этого типа данных в соответствии с компилятором. |
Методы
Типы данных имеют следующий метод для изменения порядка байтов:
dtype.newbyteorder([new_order]) | Возвращает новый тип данных с другим порядком байтов. |
Следующие методы реализуют протокол pickle:
dtype.__reduce__ | помощник для pickle |
dtype.__setstate__ |
© 2005–2019 NumPy Developers
Licensed under the 3-clause BSD License.
https://docs.scipy.org/doc/numpy-1.16.1/reference/arrays.dtypes.html