标量#
Python 只定义了特定数据类的一种类型(只有一种整数类型,一种浮点类型等). 这在不需要关心数据在计算机中表示的所有方式的应用程序中可能很方便. 但是,对于科学计算,通常需要更多的控制.
在 NumPy 中,有 24 个新的基本 Python 类型来描述不同类型的标量. 这些类型描述符主要基于 CPython 使用 C 语言编写的类型,以及与 Python 类型兼容的几种附加类型.
数组标量具有与 ndarrays 相同的属性和方法. [1] 这使得人们可以部分地将数组的项目视为与数组相同的地位,从而消除混合标量和数组运算时产生的粗糙边缘.
数组标量存在于数据类型的层次结构中(见下图). 它们可以使用层次结构来检测:例如,如果 val 是数组标量对象,则 isinstance(val, np.generic) 将返回 True . 或者,可以使用数据类型层次结构的其他成员来确定存在的数组标量的类型. 因此,例如,如果 val 是一个复数值类型,则 isinstance(val, np.complexfloating) 将返回 True ,而如果 val 是灵活的 itemsize 数组类型( str_ , bytes_ , void )之一,则 isinstance(val, np.flexible) 将返回 true.
图:表示数组数据类型的类型对象层次结构. 未显示的是用于索引的两个整数类型 intp 和 uintp (自 NumPy 2 以来与默认整数相同).#
内置标量类型#
内置标量类型如下所示. 类似 C 的名称与字符代码相关联,这些字符代码显示在其描述中. 但是,不鼓励使用字符代码.
某些标量类型本质上等同于基本 Python 类型,因此它们也从通用数组标量类型继承:
数组标量类型 |
相关 Python 类型 |
继承? |
|---|---|---|
否 |
||
是 |
||
是 |
||
是 |
||
是 |
||
否 |
||
否 |
||
否 |
bool_ 数据类型与 Python bool 非常相似,但不从它继承,因为 Python 的 bool 不允许自己被继承,并且在 C 级别上,实际 bool 数据的大小与 Python 布尔标量的大小不同.
小技巧
NumPy 中的默认数据类型是 double .
- class numpy.generic[源代码]#
numpy 标量类型的基类.
大多数(所有?)numpy 标量类型都派生自此类.为了保持一致性,它公开了与
ndarray相同的 API,尽管许多相随的属性要么是“只读”的,要么是完全不相关的.强烈建议用户从此类派生自定义标量类型.
整数类型#
备注
numpy 整数类型反映了 C 整数的行为,因此可能会受到 溢出错误 的影响.
有符号整数类型#
- class numpy.byte[源代码]#
有符号整数类型,与 C
char兼容.- 字符代码:
'b'- 规范名称:
- 在此平台(Linux x86_64)上的别名:
numpy.int8: 8 位有符号整数(-128到127).
- class numpy.short[源代码]#
有符号整数类型,与 C
short兼容.- 字符代码:
'h'- 规范名称:
- 在此平台(Linux x86_64)上的别名:
numpy.int16: 16 位有符号整数(-32_768到32_767).
- class numpy.intc[源代码]#
有符号整数类型,与 C
int兼容.- 字符代码:
'i'- 规范名称:
- 在此平台(Linux x86_64)上的别名:
numpy.int32: 32 位有符号整数(-2_147_483_648到2_147_483_647).
- class numpy.int_[源代码]#
默认有符号整数类型,在 64 位系统上为 64 位,在 32 位系统上为 32 位.
- 字符代码:
'l'- 规范名称:
- 在此平台(Linux x86_64)上的别名:
numpy.int64: 64 位有符号整数(-9_223_372_036_854_775_808到9_223_372_036_854_775_807).- 在此平台(Linux x86_64)上的别名:
numpy.intp: 有符号整数,大小足以容纳指针,与 Cintptr_t兼容.
无符号整数类型#
- class numpy.ubyte[源代码]#
无符号整数类型,与 C
unsigned char兼容.- 字符代码:
'B'- 规范名称:
- 在此平台(Linux x86_64)上的别名:
numpy.uint8: 8 位无符号整数(0到255).
- class numpy.ushort[源代码]#
无符号整数类型,与 C
unsigned short兼容.- 字符代码:
'H'- 规范名称:
- 在此平台(Linux x86_64)上的别名:
numpy.uint16: 16 位无符号整数(0到65_535).
- class numpy.uintc[源代码]#
无符号整数类型,与 C
unsigned int兼容.- 字符代码:
'I'- 规范名称:
- 在此平台(Linux x86_64)上的别名:
numpy.uint32: 32 位无符号整数(0到4_294_967_295).
- class numpy.uint[源代码]#
无符号整数类型,在 64 位系统上为 64 位,在 32 位系统上为 32 位.
- 字符代码:
'L'- 规范名称:
- 在此平台(Linux x86_64)上的别名:
numpy.uint64: 64 位无符号整数(0到18_446_744_073_709_551_615).- 在此平台(Linux x86_64)上的别名:
numpy.uintp: 无符号整数,大小足以容纳指针,与 Cuintptr_t兼容.
非精确类型#
备注
非精确标量在使用最少的十进制数字进行打印,通过合理的舍入,使其值与相同数据类型的其他值区分开来.请参见 format_float_positional 和 format_float_scientific 的 unique 参数.
这意味着具有相等二进制值但数据类型精度不同的变量可能会以不同的方式显示:
>>> import numpy as np
>>> f16 = np.float16("0.1")
>>> f32 = np.float32(f16)
>>> f64 = np.float64(f32)
>>> f16 == f32 == f64
True
>>> f16, f32, f64
(0.1, 0.099975586, 0.0999755859375)
请注意,这些浮点数都没有精确的值 \(\frac{1}{10}\) ; f16 显示为 0.1 ,因为它尽可能接近该值,而其他类型则不然,因为它们具有更高的精度,因此具有更接近的值.
相反,近似于相同十进制值的不同精度的浮点标量可能比较不相等,尽管打印结果相同:
>>> f16 = np.float16("0.1")
>>> f32 = np.float32("0.1")
>>> f64 = np.float64("0.1")
>>> f16 == f32 == f64
False
>>> f16, f32, f64
(0.1, 0.1, 0.1)
浮点类型#
- class numpy.half[源代码]#
半精度浮点数类型.
- 字符代码:
'e'- 规范名称:
- 在此平台(Linux x86_64)上的别名:
numpy.float16: 16 位精度浮点数类型:符号位,5 位指数,10 位尾数.
- class numpy.single[源代码]#
单精度浮点数类型,与 C
float兼容.- 字符代码:
'f'- 规范名称:
- 在此平台(Linux x86_64)上的别名:
numpy.float32: 32 位精度浮点数类型:符号位,8 位指数,23 位尾数.
- class numpy.double(x=0, /)[源代码]#
双精度浮点数类型,与 Python
float和 Cdouble兼容.- 字符代码:
'd'- 规范名称:
- 在此平台(Linux x86_64)上的别名:
numpy.float64: 64 位精度浮点数类型:符号位,11 位指数,52 位尾数.
- class numpy.longdouble[源代码]#
扩展精度浮点数类型,与 C
long double兼容,但不一定与 IEEE 754 四精度兼容.- 字符代码:
'g'- 在此平台(Linux x86_64)上的别名:
numpy.float128: 128 位扩展精度浮点数类型.
复数浮点类型#
- class numpy.csingle[源代码]#
由两个单精度浮点数组成的复数类型.
- 字符代码:
'F'- 规范名称:
- 在此平台(Linux x86_64)上的别名:
numpy.complex64: 由 2 个 32 位精度浮点数组成的复数类型.
- class numpy.cdouble(real=0, imag=0)[源代码]#
由两个双精度浮点数组成的复数类型,与 Python
complex兼容.- 字符代码:
'D'- 规范名称:
- 在此平台(Linux x86_64)上的别名:
numpy.complex128: 由 2 个 64 位精度浮点数组成的复数类型.
- class numpy.clongdouble[源代码]#
由两个扩展精度浮点数组成的复数类型.
- 字符代码:
'G'- 在此平台(Linux x86_64)上的别名:
numpy.complex256: 由 2 个 128 位扩展精度浮点数组成的复数类型.
其他类型#
- class numpy.datetime64[源代码]#
如果从 64 位整数创建,它表示自
1970-01-01T00:00:00以来的偏移量. 如果从字符串创建,则该字符串可以是 ISO 8601 日期或日期时间格式.当解析字符串以创建 datetime 对象时,如果字符串包含尾随时区(‘Z’ 或时区偏移量),则该时区将被删除并给出用户警告.
Datetime64 对象应被视为 UTC,因此偏移量为 +0000.
>>> np.datetime64(10, 'Y') np.datetime64('1980') >>> np.datetime64('1980', 'Y') np.datetime64('1980') >>> np.datetime64(10, 'D') np.datetime64('1970-01-11')
有关更多信息,请参见 日期时间和时间增量 .
- 字符代码:
'M'
备注
实际上存储在对象数组(即,具有 dtype object_ 的数组)中的数据是对 Python 对象的引用,而不是对象本身. 因此,对象数组的行为更像通常的 Python lists ,因为它们的内容不必是相同的 Python 类型.
对象类型也很特殊,因为包含 object_ 项的数组在项目访问时不会返回 object_ 对象,而是返回数组项引用的实际对象.
以下数据类型是灵活的:它们没有预定义的大小,并且它们描述的数据在不同的数组中可以具有不同的长度.(在字符代码中, # 是一个整数,表示数据类型由多少个元素组成.)
- class numpy.flexible[源代码]#
所有没有预定义长度的标量类型的抽象基类.这些类型的实际大小取决于特定的
numpy.dtype实例化.
- class numpy.str_[源代码]#
一个 Unicode 字符串.
此类型会去除尾部的空码位.
>>> s = np.str_("abc\x00") >>> s 'abc'
与内置的
str不同,它支持 Buffer Protocol ,将其内容公开为 UCS4:>>> m = memoryview(np.str_("abc")) >>> m.format '3w' >>> m.tobytes() b'a\x00\x00\x00b\x00\x00\x00c\x00\x00\x00'
- 字符代码:
'U'
- class numpy.void(length_or_data, /, dtype=None)[源代码]#
创建一个新的结构化或非结构化 void 标量.
- 参数:
注释
由于历史原因,并且由于 void 标量可以表示任意字节数据和结构化 d 类型,因此 void 构造函数具有三种调用约定:
np.void(5)创建一个填充了五个\0字节的dtype="V5"标量. 5 可以是 Python 或 NumPy 整数.np.void(b"bytes-like")从字节字符串创建一个 void 标量. dtype itemsize 将与字节字符串长度匹配,此处为"V10".当传递
dtype=时,该调用与数组创建大致相同. 但是,返回的是 void 标量而不是数组.
请参阅示例,其中显示了所有三种不同的约定.
示例
>>> np.void(5) np.void(b'\x00\x00\x00\x00\x00') >>> np.void(b'abcd') np.void(b'\x61\x62\x63\x64') >>> np.void((3.2, b'eggs'), dtype="d,S5") np.void((3.2, b'eggs'), dtype=[('f0', '<f8'), ('f1', 'S5')]) >>> np.void(3, dtype=[('x', np.int8), ('y', np.int8)]) np.void((3, 3), dtype=[('x', 'i1'), ('y', 'i1')])
- 字符代码:
'V'
警告
参见 Note on string types .
数字兼容性:如果您在数字代码中使用了旧的类型代码字符(这从未被推荐),则需要将其中一些更改为新字符. 特别是,需要进行的更改是 c -> S1 , b -> B , 1 -> b , s -> h , w -> H 和 u -> I . 这些更改使类型字符约定与 struct 模块等其他 Python 模块更加一致.
大小别名#
除了它们(主要)从 C 派生的名称之外,整数,浮点数和复数数据类型也可以使用位宽约定来使用,以便始终可以确保正确大小的数组.还提供了指向足够大的整数类型以容纳 C 指针的两个别名( numpy.intp 和 numpy.uintp ).
- numpy.int8[源代码]#
- numpy.int16#
- numpy.int32#
- numpy.int64#
有符号整数类型的别名(
numpy.byte,numpy.short,numpy.intc,numpy.int_,numpy.long和numpy.longlong之一),具有指定的位数.分别与 C99
int8_t,int16_t,int32_t和int64_t兼容.
- numpy.uint8[源代码]#
- numpy.uint16#
- numpy.uint32#
- numpy.uint64#
无符号整数类型的别名(
numpy.ubyte,numpy.ushort,numpy.uintc,numpy.uint,numpy.ulong和numpy.ulonglong之一),具有指定的位数.分别与 C99
uint8_t,uint16_t,uint32_t和uint64_t兼容.
- numpy.intp[源代码]#
有符号整数类型的别名(
numpy.byte,numpy.short,numpy.intc,numpy.int_,numpy.long和numpy.longlong之一),用作默认整数并用于索引.与 C
Py_ssize_t兼容.- 字符代码:
'n'
在 2.0 版本发生变更: 在 NumPy 2 之前,它的大小与指针相同.实际上这几乎总是相同的,但字符代码
'p'映射到 Cintptr_t.字符代码'n'是在 NumPy 2.0 中添加的.
- numpy.uintp[源代码]#
与
intp大小相同的无符号整数类型的别名.与 C
size_t兼容.- 字符代码:
'N'
在 2.0 版本发生变更: 在 NumPy 2 之前,它的大小与指针相同.实际上这几乎总是相同的,但字符代码
'P'映射到 Cuintptr_t.字符代码'N'是在 NumPy 2.0 中添加的.
- numpy.float96#
- numpy.float128[源代码]#
numpy.longdouble的别名,以其位大小命名.这些别名的存在取决于平台.
- numpy.complex192#
- numpy.complex256[源代码]#
numpy.clongdouble的别名,以其位大小命名.这些别名的存在取决于平台.
属性#
数组标量对象具有 array priority NPY_SCALAR_PRIORITY (-1,000,000.0). 它们也(尚未)没有 ctypes 属性. 否则,它们与数组共享相同的属性:
标志的整数值. |
|
数组维度的元组. |
|
每个维度中的字节步长的元组. |
|
数组维度的数量. |
|
指向数据起点的指针. |
|
gentype 中的元素数量. |
|
一个元素的长度,以字节为单位. |
|
与相应数组属性相同的标量属性. |
|
获取数组数据描述符. |
|
标量的实部. |
|
标量的虚部. |
|
标量的一维视图. |
|
与相应数组属性相同的标量属性. |
|
数组协议:Python 端 |
|
数组协议:结构体 |
|
数组优先级. |
|
标量类型的 __array_wrap__ 实现 |
索引#
参见
数组标量可以像 0 维数组一样进行索引:如果 x 是一个数组标量,
x[()]返回数组标量的副本x[...]返回一个 0 维ndarrayx['field-name']返回 field-name 字段中的数组标量.(x 可以有字段,例如,当它对应于结构化数据类型时.)
方法#
数组标量具有与数组完全相同的方法.这些方法的默认行为是在内部将标量转换为等效的 0 维数组,并调用相应的数组方法.此外,数组标量上的数学运算被定义为设置和使用与 ufunc 相同硬件标志来解释结果,以便用于 ufunc 的错误状态也传递到数组标量上的数学运算.
上述规则的例外情况如下:
sc.__array__(dtype) 从具有指定 dtype 的标量返回 0 维数组 |
|
标量类型的 __array_wrap__ 实现 |
|
与相应数组属性相同的标量方法. |
|
与相应数组属性相同的标量方法. |
|
pickle 的辅助方法. |
|
与相应数组属性相同的标量方法. |
用于 typing 的实用工具方法:
|
返回 |
定义新类型#
有两种有效的方法来定义新的数组标量类型(除了 dtypes 从内置标量类型组成结构化类型):一种方法是简单地子类化 ndarray 并覆盖感兴趣的方法.这在一定程度上是可行的,但内部某些行为由数组的数据类型决定.要完全自定义数组的数据类型,您需要定义一种新的数据类型,并将其注册到 NumPy 中.这种新类型只能在 C 中使用 NumPy C-API 定义.