数据类型对象 (dtype)#

数据类型对象(numpy.dtype 类的实例)描述了如何解释对应于数组项的固定大小内存块中的字节。它描述了数据的以下方面

  1. 数据的类型(整数、浮点数、Python 对象等)

  2. 数据的大小(例如,整数中有多少字节)

  3. 数据的字节序(小端大端

  4. 如果数据类型是 结构化数据类型,其他数据类型的聚合(例如,描述由整数和浮点数组成的数组项),

    1. 结构的“字段”的名称是什么,可以通过它们进行 访问

    2. 每个 字段 的数据类型是什么,以及

    3. 每个字段占据内存块的哪一部分。

  5. 如果数据类型是子数组,则其形状和数据类型是什么。

为了描述标量数据的类型,NumPy 中有几种用于各种精度整数、浮点数等的 内置标量类型。从数组中提取的项(例如,通过索引)将是一个 Python 对象,其类型与数组的数据类型关联的标量类型。

请注意,标量类型不是 dtype 对象,即使在 NumPy 中需要数据类型规范时,它们可以用作数据类型对象。

结构化数据类型是通过创建其 字段 包含其他数据类型的数据类型来形成的。每个字段都有一个名称,可以通过该名称进行 访问。父数据类型的大小应足以包含其所有字段;父类型几乎总是基于 void 类型,该类型允许任意项大小。结构化数据类型也可以在其字段中包含嵌套的结构化子数组数据类型。

最后,数据类型可以描述本身就是另一个数据类型项的数组的项。

如果使用描述子数组的数据类型创建数组,则在创建数组时,子数组的维度将附加到数组的形状。结构化类型字段中的子数组的行为有所不同,请参阅 字段访问

子数组始终具有 C 连续的内存布局。

示例

包含 32 位大端整数的简单数据类型:(有关构造的详细信息,请参阅 指定和构造数据类型

>>> 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('<U16')
>>> dt['grades']
dtype(('<f8', (2,)))

此数据类型数组的项包装在 数组标量 类型中,该类型也具有两个字段

>>> 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])
<class 'numpy.void'>
>>> type(x[1]['grades'])
<class 'numpy.ndarray'>

指定和构造数据类型#

在 NumPy 函数或方法中需要数据类型时,可以提供 dtype 对象或可以转换为 dtype 对象的任何内容。这些转换由 dtype 构造函数执行

dtype(dtype[, align, copy])

创建一个数据类型对象。

下面描述了可以转换为数据类型对象的内容

dtype 对象

按原样使用。

None

默认数据类型:float64

数组标量类型

24 个内置的 数组标量类型对象 都转换为关联的数据类型对象。这对它们的子类也适用。

请注意,并非所有数据类型信息都可以用类型对象提供:例如,flexible 数据类型具有 0 的默认 itemsize,并且需要显式给定的大小才能有用。

示例

>>> 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 数组,即使 float32np.floating 的子类型。

内置 Python 类型

一些 Python 类型在用于生成 dtype 对象时等效于相应的数组标量

请注意,str_ 对应于 UCS4 编码的 Unicode 字符串。

示例

>>> 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 对象的内容。

可以转换几种字符串。识别的字符串可以在前面加上 '>'大端)、'<'小端)或 '='(硬件原生,默认值),以指定字节序。

单字符字符串

每个内置数据类型都有一个字符代码(更新的 Numeric 类型代码),该代码唯一地标识它。

示例

>>> import numpy as np
>>> 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 除外,在 Unicode 中,它被解释为字符数。项目大小必须对应于现有类型,否则将引发错误。支持的类型包括

'?'

布尔值

'b'

(有符号)字节

'B'

无符号字节

'i'

(有符号)整数

'u'

无符号整数

'f'

浮点数

'c'

复数浮点数

'm'

时间增量

'M'

日期时间

'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 的现有代码向后兼容,Sa 类型字符串是以零结尾的字节。对于 Unicode 字符串,请使用 Unumpy.str_。对于不需要零终止的有符号字节,可以使用 bi1

带逗号分隔字段的字符串

指定结构化数据类型格式的简写表示法是基本格式的逗号分隔字符串。

在此上下文中,基本格式是可选的形状说明符后跟数组协议类型字符串。如果形状具有多个维度,则需要括号。NumPy 允许修改格式,因为任何可以唯一标识类型的字符串都可以用来在字段中指定数据类型。生成的字段名为 'f0''f1'、…、'f<N-1>',其中 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 dtype 的任何字符串名称,例如

示例

>>> import numpy as np
>>> dt = np.dtype('uint32')   # 32-bit unsigned integer
>>> dt = np.dtype('float64')  # 64-bit floating-point number
(flexible_dtype, itemsize)

第一个参数必须是转换为零大小灵活数据类型对象的任何对象,第二个参数是提供所需 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
[(字段名, 字段数据类型, 字段形状), ...]

obj 应该是一个字段列表,每个字段由长度为 2 或 3 的元组描述。(等价于 __array_interface__ 属性中的 descr 项目。)

第一个元素,field_name,是字段名称(如果这是 '',则分配标准字段名称 'f#')。字段名称也可以是字符串的 2 元组,其中第一个字符串是字段的“标题”(可以是任何字符串或 Unicode 字符串)或元数据(可以是任何对象),第二个字符串是“名称”(必须是有效的 Python 标识符)。

第二个元素,field_dtype,可以是任何可以解释为数据类型的东西。

可选的第三个元素 field_shape 包含形状,如果此字段表示第二个元素中数据类型的数组。请注意,具有等于 1 的第三个参数的 3 元组等价于 2 元组。

此样式不接受 dtype 构造函数中的 align,因为它假设所有内存都由数组接口描述来解释。

示例

具有字段 big(大端 32 位整数)和 little(小端 32 位整数)的数据类型

>>> import numpy as np
>>> dt = np.dtype([('big', '>i4'), ('little', '<i4')])

具有字段 RGBA 的数据类型,每个都是无符号的 8 位整数

>>> dt = np.dtype([('R','u1'), ('G','u1'), ('B','u1'), ('A','u1')])
{'names': ..., 'formats': ..., 'offsets': ..., 'titles': ..., 'itemsize': ...}

此样式有两个必需键和三个可选键。namesformats 键是必需的。它们各自的值是等长列表,包含字段名称和字段格式。字段名称必须是字符串,字段格式可以是 dtype 构造函数接受的任何对象。

当提供可选键 offsetstitles 时,它们的值必须与 namesformats 列表具有相同的长度。offsets 值是每个字段的字节偏移量列表(限制为 ctypes.c_int),而 titles 值是每个字段的标题列表(如果某个字段不需要标题,则可以使用 None)。titles 可以是任何对象,但当 str 对象时,将在字段字典中添加另一个条目,该条目以标题为键,并引用包含标题作为附加元组成员的相同字段元组。

itemsize 键允许设置 dtype 的总大小,并且必须是足够大的整数,以便所有字段都在 dtype 内。如果正在构造的 dtype 已对齐,则 itemsize 也必须可被结构对齐整除。dtype 的总 itemsize 限制为 ctypes.c_int

示例

具有字段 rgba 的数据类型,每个都是 8 位无符号整数

>>> import numpy as np
>>> dt = np.dtype({'names': ['r','g','b','a'],
...                'formats': [np.uint8, np.uint8, np.uint8, np.uint8]})

具有字段 rb(带有给定的标题)的数据类型,两者都是 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 应该包含字符串或 Unicode 键,这些键引用 (数据类型, 偏移量)(数据类型, 偏移量, 标题) 元组。

示例

包含字段 col1(字节位置 0 处的 10 字符字符串)、col2(字节位置 10 处的 32 位浮点数)和 col3(字节位置 14 处的整数)的数据类型

>>> import numpy as np
>>> dt = np.dtype({'col1': ('U10', 0), 'col2': (np.float32, 10),
...                'col3': (int, 14)})
(基础数据类型, 新数据类型)

在 NumPy 1.7 及更高版本中,此表单允许将 base_dtype 解释为结构化 dtype。使用此 dtype 创建的数组将具有底层 dtype base_dtype,但将具有来自 new_dtype 的字段和标志。这对于创建自定义结构化 dtype 很有用,如 记录数组 中所做的那样。

此表单还使指定具有重叠字段的结构 dtype 成为可能,其功能类似于 C 中的“联合”类型。但是,不建议使用此用法,建议使用联合机制。

两个参数都必须可转换为具有相同总大小的数据类型对象。

示例

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 位整数,包含字段 rgba,它们将整数中的 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 处理。

示例

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

一个字符代码('biufcmMOSUV' 之一),标识数据的一般类型。

dtype.char

21 种不同的内置类型中每种类型的唯一字符代码。

dtype.num

21 种不同的内置类型中每种类型的唯一数字。

dtype.str

此数据类型对象的数组协议类型字符串。

数据的大小依次由以下内容描述

dtype.name

此数据类型的位宽名称。

dtype.itemsize

此数据类型对象的数据元素大小。

此数据的字节序

dtype.byteorder

指示此数据类型对象的字节序的字符。

有关 结构化数据类型 中子数据类型的信息

dtype.fields

为此数据类型定义的命名字段的字典,或 None

dtype.names

字段名称的有序列表,如果不存在字段,则为 None

对于描述子数组的数据类型

dtype.subdtype

如果此 dtype 描述子数组,则为元组 (项目数据类型, 形状),否则为 None。

dtype.shape

如果此数据类型描述子数组,则为子数组的形状元组,否则为 ()

提供附加信息的属性

dtype.hasobject

布尔值,指示此 dtype 是否在任何字段或子 dtype 中包含任何引用计数对象。

dtype.flags

描述如何解释此数据类型的位标志。

dtype.isbuiltin

整数,指示此 dtype 与内置 dtype 的关系。

dtype.isnative

布尔值,指示此 dtype 的字节序是否为平台的本地字节序。

dtype.descr

数据类型的 __array_interface__ 描述。

dtype.alignment

根据编译器,此数据类型所需的对齐方式(字节)。

dtype.base

返回子数组基本元素的 dtype,无论其维度或形状如何。

用户附加的元数据

dtype.metadata

要么是 None,要么是元数据的只读字典(mappingproxy)。

方法#

数据类型具有以下用于更改字节序的方法

dtype.newbyteorder([new_order])

返回具有不同字节序的新 dtype。

以下方法实现 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<value。