数据类型对象 (dtype)#
数据类型对象(numpy.dtype 类的实例)描述了与数组项对应的固定大小内存块中的字节如何被解释。它描述了数据的以下方面:
数据的类型(整数、浮点数、Python 对象等)
数据的大小(例如,整数占用多少字节)
如果数据类型是结构化数据类型,是其他数据类型的聚合(例如,描述由一个整数和一个浮点数组成的数组项),则:
如果数据类型是子数组,则其形状和数据类型是什么。
为了描述标量数据的类型,NumPy 提供了几种内置标量类型,用于表示不同精度的整数、浮点数等。从数组中提取的项(例如,通过索引)将是 Python 对象,其类型是与数组数据类型关联的标量类型。
请注意,标量类型不是dtype 对象,即使它们可以在需要数据类型规范的 NumPy 位置中替代 dtype 对象。
结构化数据类型是通过创建一种数据类型来形成的,该数据类型的字段包含其他数据类型。每个字段都有一个名称,可以通过该名称进行访问。父数据类型的大小必须足以容纳其所有字段;父数据类型几乎总是基于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 构造函数执行:
|
-- |
下面描述了可以转换为数据类型对象的内容。
- 数组标量类型
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是np.floating的子类型,也会将float32数组转换为float64数组。
- 内置 Python 类型
一些 Python 类型在生成
dtype对象时等同于相应的数组标量:Python 类型
NumPy 类型
(其他所有)
请注意,
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 除外,其解释为字符数,并且
b1表示布尔值。项大小必须对应于现有类型,否则将引发错误。支持的种类是:'?'、'b1'布尔值
'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 的现有代码兼容,
S和a类型字符串是零终止字节。对于 Unicode 字符串,请使用U,numpy.str_。对于不需要零终止的有符号字节,可以使用b或i1。- 带逗号分隔字段的字符串
指定结构化数据类型格式的简写表示法是逗号分隔的基本格式字符串。
在此上下文中,基本格式是可选的形状说明符,后跟一个数组协议类型字符串。如果形状有多个维度,则必须使用括号。NumPy 允许对格式进行修改,即任何能够唯一标识类型的字符串都可以用于指定字段中的数据类型。生成的数据类型字段命名为
'f0'、'f1'、……、'f<N-1>',其中 N (>1) 是字符串中逗号分隔的基本格式的数量。如果提供了可选的形状说明符,则数据类型将描述一个子数组。示例
字段命名为
f0,包含一个 32 位整数字段命名为
f1,包含一个 2x3 的 64 位浮点数子数组字段命名为
f2,包含一个 32 位浮点数>>> import numpy as np >>> dt = np.dtype("i4, (2,3)f8, f4")
字段命名为
f0,包含一个 3 个字符的字符串字段命名为
f1,包含一个形状为 (3,) 的 64 位无符号整数子数组字段命名为
f2,包含一个形状为 3x4 的 10 个字符的 Unicode 字符串子数组>>> 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)第一个参数必须是一个可转换为零大小的灵活数据类型对象,第二个参数是一个提供所需项大小的整数。
示例
>>> 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)第一个参数是任何可以转换为固定大小数据类型对象的对象。第二个参数是所需形状。如果形状参数为 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 的元组描述。(等同于
__array_interface__属性中的descr项。)第一个元素 *field_name* 是字段名(如果为空字符串
'',则分配一个标准字段名'f#')。字段名也可以是字符串元组,其中第一个字符串可以是“标题”(可以是任何字符串或 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')])
具有字段
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* 可以是任何对象,但当str对象时,会向字段字典添加另一个条目,该条目以标题为键,并引用相同的字段元组,该元组将包含标题作为附加的元组成员。*itemsize* 键允许设置 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* 应包含字符串或 Unicode 键,这些键引用
(data-type, offset)或(data-type, offset, title)元组。示例
数据类型包含字段
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)})
(base_dtype, new_dtype)在 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 位整数,包含字段
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 来处理。
示例
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 与内置 dtype 的关系。 |
|
布尔值,指示此 dtype 的字节顺序是否是平台的原生顺序。 |
|
__array_interface__ 数据类型的描述。 |
|
根据编译器,此数据类型的必需对齐(字节)。 |
|
返回子数组的基本元素的 dtype,无论其维度或形状如何。 |
用户附加的元数据
为 |
方法#
数据类型具有用于更改字节顺序的方法:
|
返回具有不同字节顺序的新 dtype。 |
以下方法实现 pickle 协议:
Pickle的助手。 |
|
用于类型的实用方法
|
返回 |
比较操作
|
返回 self>=value。 |
|
返回 self>value。 |
|
返回 self<=value。 |
|
返回 self<value。 |