数据类型对象 ( dtype )#
数据类型对象( numpy.dtype 类的实例)描述了如何解释对应于数组项的固定大小内存块中的字节.它描述了数据的以下几个方面:
数据的类型(整数,浮点数,Python 对象等)
数据的大小(例如,整数中有多少个字节)
数据的字节顺序( little-endian 或 big-endian )
如果数据类型是 structured data type ,即其他数据类型的聚合(例如,描述一个由整数和浮点数组成的数组项),
如果数据类型是子数组,那么它的形状和数据类型是什么.
为了描述标量数据的类型,NumPy 中有几个 built-in scalar types ,用于各种精度的整数,浮点数等.从数组中提取的项目(例如,通过索引)将是一个 Python 对象,其类型是与数组数据类型关联的标量类型.
请注意,标量类型不是 dtype 对象,即使当需要在 NumPy 中指定数据类型时,它们可以代替使用.
结构化数据类型是通过创建一个 field 包含其他数据类型的数据类型来形成的.每个字段都有一个名称,可以通过该名称 accessed .父数据类型应该足够大,能够包含其所有字段;父类型几乎总是基于 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,)))
此数据类型数组的项目包装在也具有两个字段的 array scalar 类型中:
>>> 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 构造函数完成:
|
创建数据类型对象. |
下面描述了可以转换为数据类型对象的内容:
- 数组标量类型
24 个内置的 array scalar type objects 都转换为关联的数据类型对象.它们的子类也是如此.
请注意,并非所有数据类型信息都可以通过类型对象提供:例如,
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 类型
当用于生成
dtype对象时,一些 Python 类型等同于相应的数组标量: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 对象的内容.
可以转换几种字符串.识别的字符串可以加上 '>' ( 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('<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)示例
>>> 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,因为它假定所有内存都由 array interface 描述来解释.示例
具有字段
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). 标题可以是任何对象,但是当str对象时,将向 fields 字典添加另一个条目,该条目以标题为键,并引用包含标题作为附加元组成员的相同字段元组.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 应包含引用
(data-type, offset)或(data-type, offset, title)元组的字符串或 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)})
(base_dtype, new_dtype)在 NumPy 1.7 及更高版本中,此形式允许将 base_dtype 解释为结构化 dtype. 使用此 dtype 创建的数组将具有底层 dtype base_dtype ,但将具有从 new_dtype 获取的字段和标志. 这对于创建自定义结构化 dtype 很有用,如 record arrays 中所做的那样.
这种形式还可以指定具有重叠字段的结构 dtype,其功能类似于 C 中的"union"类型. 但是,不建议使用此用法,并且首选 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种不同内置类型的唯一数字. |
|
此数据类型对象的数组协议类型字符串. |
数据的大小又由以下各项描述:
此数据类型的位宽名称. |
|
此数据类型对象的元素大小. |
此数据的字节序:
一个字符, 指示此数据类型对象的字节顺序. |
有关 structured data type 中的子数据类型的信息:
为此数据类型定义的命名字段的字典,或 |
|
字段名称的有序列表,如果没有字段,则为 |
对于描述子数组的数据类型:
如果此 |
|
如果此数据类型描述一个子数组,则为子数组的 shape 元组,否则为 |
提供附加信息的属性:
一个布尔值,指示此 dtype 是否在任何字段或子 dtype 中包含任何引用计数对象. |
|
描述如何解释此数据类型的位标志. |
|
整数,指示此 dtype 与内置 dtype 的关系. |
|
一个布尔值,指示此 dtype 的字节顺序是否为平台的本机字节顺序. |
|
数据类型的 |
|
根据编译器,此数据类型所需的对齐方式(字节). |
|
返回子数组的基本元素的 dtype,无论其维度或形状如何. |
用户附加的元数据:
|
方法#
数据类型具有以下方法来更改字节顺序:
|
返回具有不同字节顺序的新 dtype. |
以下方法实现了 pickle 协议:
pickle 的助手. |
|
用于类型的实用程序方法:
|
返回 |
比较运算:
|
返回 self>=value. |
|
返回 self>value. |
|
返回 self<=value. |
|
返回自身<value. |