数据类型对象 (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
数组转换为float64
数组,即使float32
是np.floating
的子类型。
- 内置 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 除外,其中它被解释为字符数。项大小必须对应现有类型,否则将引发错误。支持的类型包括
'?'
布尔型
'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
的字段,包含一个 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
[(field_name, field_dtype, field_shape), ...]
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')])
字段
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 中的“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
处理。
示例
一个 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__ 描述。 |
|
根据编译器,此数据类型所需的对齐(字节)。 |
|
返回子数组基本元素的 dtype,无论其维度或形状如何。 |
用户附加的元数据
|
方法#
数据类型具有以下用于更改字节顺序的方法
|
返回一个具有不同字节顺序的新 dtype。 |
以下方法实现了 pickle 协议
pickle 的辅助函数。 |
|
类型化实用方法
|
返回围绕 |
比较操作
|
返回 self>=value。 |
|
返回 self>value。 |
|
返回 self<=value。 |
|
返回 self<value。 |