标量#
Python 仅定义了一种特定数据类的类型(只有一种整数类型、一种浮点数类型等)。这在不需要关注数据在计算机中表示的所有方式的应用程序中可能很方便。但是,对于科学计算,通常需要更多控制。
在 NumPy 中,有 24 种新的基本 Python 类型来描述不同类型的标量。这些类型描述符主要基于 CPython 编写的 C 语言中可用的类型,以及与 Python 类型兼容的几种其他类型。
数组标量具有与 ndarrays
相同的属性和方法。[1] 这允许人们将数组的项目部分地视为与数组相同,从而平滑混合标量和数组操作时产生的粗糙边缘。
数组标量位于数据类型的层次结构中(参见下图)。可以使用层次结构检测它们:例如,isinstance(val, np.generic)
如果 val 是一个数组标量对象,则将返回 True
。或者,可以使用数据类型层次结构的其他成员来确定存在哪种数组标量。因此,例如 isinstance(val, np.complexfloating)
如果 val 是一个复数值类型,则将返回 True
,而 isinstance(val, np.flexible)
如果 val 是灵活的项目大小数组类型之一(str_
、bytes_
、void
),则将返回 true。
内置标量类型#
内置标量类型如下所示。C 风格的名称与字符代码相关联,这些代码显示在其描述中。但是,不建议使用字符代码。
一些标量类型本质上等效于基本 Python 类型,因此也从它们以及通用数组标量类型继承
数组标量类型 |
相关的 Python 类型 |
继承? |
---|---|---|
仅限 Python 2 |
||
是 |
||
是 |
||
是 |
||
是 |
||
否 |
||
否 |
||
否 |
bool_
数据类型与 Python bool
非常相似,但没有从它继承,因为 Python 的 bool
不允许从它继承,并且在 C 层面上,实际 bool 数据的大小与 Python 布尔标量不同。
提示
NumPy 中的默认数据类型是 double
。
- class numpy.generic[source]#
NumPy 标量类型的基类。
大多数(全部?)NumPy 标量类型从中派生的类。为了保持一致性,它公开了与
ndarray
相同的 API,尽管许多后续属性要么是“只读”的,要么完全不相关。这是强烈建议用户从中派生自定义标量类型的类。
整数类型#
注意
NumPy 整数类型镜像 C 整数的行为,因此可能容易受到 溢出错误 的影响。
有符号整数类型#
- class numpy.byte[source]#
有符号整数类型,与 C
char
兼容。- 字符代码:
'b'
- 规范名称:
- 此平台上的别名(Linux x86_64):
numpy.int8
:8 位有符号整数(-128
到127
)。
- class numpy.short[source]#
有符号整数类型,与 C
short
兼容。- 字符代码:
'h'
- 规范名称:
- 此平台上的别名(Linux x86_64):
numpy.int16
:16 位有符号整数(-32_768
到32_767
)。
- class numpy.intc[source]#
有符号整数类型,与 C
int
兼容。- 字符代码:
'i'
- 规范名称:
- 此平台上的别名(Linux x86_64):
numpy.int32
:32 位有符号整数(-2_147_483_648
到2_147_483_647
)。
- class numpy.int_[source]#
默认有符号整数类型,在 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[source]#
无符号整数类型,与 C
unsigned char
兼容。- 字符代码:
'B'
- 规范名称:
- 此平台上的别名(Linux x86_64):
numpy.uint8
:8 位无符号整数(0
到255
)。
- class numpy.ushort[source]#
无符号整数类型,兼容 C
unsigned short
。- 字符代码:
'H'
- 规范名称:
- 此平台上的别名(Linux x86_64):
numpy.uint16
: 16 位无符号整数(0
到65_535
)。
- class numpy.uintc[source]#
无符号整数类型,兼容 C
unsigned int
。- 字符代码:
'I'
- 规范名称:
- 此平台上的别名(Linux x86_64):
numpy.uint32
: 32 位无符号整数(0
到4_294_967_295
)。
- class numpy.uint[source]#
无符号整数类型,在 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[source]#
半精度浮点数类型。
- 字符代码:
'e'
- 规范名称:
- 此平台上的别名(Linux x86_64):
numpy.float16
: 16 位精度浮点数类型:符号位、5 位指数、10 位尾数。
- class numpy.single[source]#
单精度浮点数类型,兼容 C
float
。- 字符代码:
'f'
- 规范名称:
- 此平台上的别名(Linux x86_64):
numpy.float32
: 32 位精度浮点数类型:符号位、8 位指数、23 位尾数。
- class numpy.double(x=0, /)[source]#
双精度浮点数类型,兼容 Python
float
和 Cdouble
。- 字符代码:
'd'
- 规范名称:
- 此平台上的别名(Linux x86_64):
numpy.float64
: 64 位精度浮点数类型:符号位、11 位指数、52 位尾数。
- class numpy.longdouble[source]#
扩展精度浮点数类型,兼容 C
long double
,但不一定与 IEEE 754 四精度兼容。- 字符代码:
'g'
- 此平台上的别名(Linux x86_64):
numpy.float128
: 128 位扩展精度浮点数类型。
复数浮点类型#
- class numpy.csingle[source]#
由两个单精度浮点数组成的复数类型。
- 字符代码:
'F'
- 规范名称:
- 此平台上的别名(Linux x86_64):
numpy.complex64
: 由两个 32 位精度浮点数组成的复数类型。
- class numpy.cdouble(real=0, imag=0)[source]#
由两个双精度浮点数组成的复数类型,兼容 Python
complex
。- 字符代码:
'D'
- 规范名称:
- 此平台上的别名(Linux x86_64):
numpy.complex128
: 由两个 64 位精度浮点数组成的复数类型。
- class numpy.clongdouble[source]#
由两个扩展精度浮点数组成的复数类型。
- 字符代码:
'G'
- 此平台上的别名(Linux x86_64):
numpy.complex256
: 由两个 128 位扩展精度浮点数组成的复数类型。
其他类型#
- class numpy.datetime64[source]#
如果从 64 位整数创建,则表示相对于
1970-01-01T00:00:00
的偏移量。如果从字符串创建,则字符串可以采用 ISO 8601 日期或日期时间格式。在解析字符串以创建日期时间对象时,如果字符串包含尾随时区(“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 列表
,因为它们的内容不必是相同的 Python 类型。
对象类型也很特殊,因为包含 object_
项的数组在项访问时不会返回 object_
对象,而是返回数组项所引用的实际对象。
以下数据类型是灵活的:它们没有预定义的大小,并且它们描述的数据在不同的数组中可以具有不同的长度。(在字符代码中,#
是一个整数,表示数据类型由多少个元素组成。)
- class numpy.flexible[source]#
所有没有预定义长度的标量类型的抽象基类。这些类型的实际大小取决于具体的
numpy.dtype
实例化。
- class numpy.str_[source]#
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)[source]#
创建一个新的结构化或非结构化 void 标量。
- 参数:
- length_or_dataint, array-like, bytes-like, object
多种含义之一(请参阅注释)。非结构化 void 的长度或字节数据。或者,当提供
dtype
时,要存储在新标量中的数据。这可以是类似数组的,在这种情况下可能会返回一个数组。- dtypedtype, 可选
如果提供,则为新标量的 dtype。此 dtype 必须是“void” dtype(即结构化或非结构化 void,另请参阅 Structured datatypes)。
版本 1.24 中的新功能。
注释
由于历史原因以及 void 标量可以表示任意字节数据和结构化 dtype,因此 void 构造函数有三种调用约定
np.void(5)
创建一个dtype="V5"
标量,其中填充了五个\0
字节。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。
数值兼容性:如果您在 Numeric 代码中使用了旧的类型代码字符(从不推荐),则需要将其中一些更改为新字符。特别是,所需的更改为 c -> S1
、b -> B
、1 -> b
、s -> h
、w -> H
和 u -> I
。这些更改使类型字符约定与其他 Python 模块(如 struct
模块)更加一致。
大小别名#
除了它们(大部分)C 派生的名称外,整数、浮点数和复数数据类型也可以使用位宽约定来使用,以便始终可以确保正确大小的数组。还提供了两个别名(numpy.intp
和 numpy.uintp
),它们指向足够大的整数类型以容纳 C 指针。
- numpy.int8[source]#
- 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[source]#
- 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[source]#
用作默认整数和索引的有符号整数类型(
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[source]#
与
intp
大小相同的无符号整数类型的别名。与 C
size_t
兼容。- 字符代码:
'N'
版本 2.0 中已更改: 在 NumPy 2 之前,它的大小与指针相同。在实践中,这几乎总是相同的,但字符代码
'P'
映射到 Cuintptr_t
。字符代码'N'
是在 NumPy 2.0 中添加的。
- numpy.float96#
- numpy.float128[source]#
numpy.longdouble
的别名,以其位数命名。这些别名的存在取决于平台。
- numpy.complex192#
- numpy.complex256[source]#
numpy.clongdouble
的别名,以其位数命名。这些别名的存在取决于平台。
属性#
数组标量对象具有 array priority
NPY_SCALAR_PRIORITY
(-1,000,000.0)。它们也没有(尚未)ctypes
属性。否则,它们与数组共享相同的属性。
标志的整数值。 |
|
数组维度的元组。 |
|
每个维度中字节步长的元组。 |
|
数组维度的数量。 |
|
指向数据开头的指针。 |
|
gentype 中元素的数量。 |
|
一个元素的长度(以字节为单位)。 |
|
与相应数组属性相同的标量属性。 |
|
获取数组数据描述符。 |
|
标量的实部。 |
|
标量的虚部。 |
|
标量的一维视图。 |
|
与相应数组属性相同的标量属性。 |
|
数组协议:Python 端 |
|
数组协议:结构体 |
|
数组优先级。 |
|
sc.__array_wrap__(obj) 从数组返回标量 |
索引#
另请参阅
数组标量可以像 0 维数组一样被索引:如果 x 是一个数组标量,
x[()]
返回数组标量的副本x[...]
返回一个 0 维的ndarray
x['field-name']
返回 field-name 字段中的数组标量。(x 可以具有字段,例如,当它对应于结构化数据类型时。)
方法#
数组标量与数组具有完全相同的方法。这些方法的默认行为是将标量内部转换为等效的 0 维数组,并调用相应的数组方法。此外,数组标量上的数学运算被定义为设置并用于解释与 ufunc 相同的硬件标志的结果,以便用于 ufunc 的错误状态也延续到数组标量上的数学运算。
上面规则的例外情况如下所示
sc.__array__(dtype) 从具有指定 dtype 的标量返回 0 维数组 |
|
sc.__array_wrap__(obj) 从数组返回标量 |
|
与相应数组属性相同的标量方法。 |
|
与相应数组属性相同的标量方法。 |
|
pickle 的辅助函数。 |
|
与相应数组属性相同的标量方法。 |
用于类型的实用程序方法
|
返回围绕 |
定义新类型#
有两种方法可以有效地定义新的数组标量类型(除了从内置标量类型组合结构化类型 dtypes 之外):一种方法是简单地继承 ndarray
并覆盖感兴趣的方法。这将在一定程度上起作用,但内部某些行为由数组的数据类型固定。要完全自定义数组的数据类型,您需要定义新的数据类型,并将其注册到 NumPy。这种新类型只能在 C 中使用 NumPy C-API 定义。