标量#
Python 只定义了特定数据类的一个类型(只有一个整数类型,一个浮点类型等)。这对于不需要关注数据在计算机中所有表示方式的应用程序来说可能很方便。然而,对于科学计算,通常需要更多的控制。
在 NumPy 中,有 24 种新的基本 Python 类型来描述不同类型的标量。这些类型描述符主要基于 CPython 所用的 C 语言中可用的类型,并增加了几种与 Python 类型兼容的类型。
数组标量具有与 ndarrays
相同的属性和方法。[1] 这使得可以将数组中的项部分地与数组同等对待,从而平滑了标量和数组操作混合时产生的粗糙边缘。
数组标量存在于数据类型的层次结构中(参见下图)。它们可以使用层次结构来检测:例如,如果 val 是一个数组标量对象,isinstance(val, np.generic)
将返回 True
。另外,可以使用数据类型层次结构中的其他成员来确定存在哪种数组标量。因此,例如 isinstance(val, np.complexfloating)
如果 val 是一个复数值类型,将返回 True
;而 isinstance(val, np.flexible)
如果 val 是可变项大小数组类型(str_
、bytes_
、void
)之一,将返回 True。

图:表示数组数据类型的类型对象层次结构。图中未显示 intp
和 uintp
这两种用于索引的整数类型(与 NumPy 2 以来默认整数相同)。#
内置标量类型#
内置标量类型如下所示。类 C 的名称与字符代码相关联,字符代码在其描述中显示。但是,不鼓励使用字符代码。
一些标量类型本质上等同于基本的 Python 类型,因此它们也继承自这些类型以及泛型数组标量类型。
数组标量类型 |
相关 Python 类型 |
继承自? |
---|---|---|
否 |
||
是 |
||
是 |
||
是 |
||
是 |
||
否 |
||
否 |
||
否 |
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
: 由2个32位精度浮点数组成的复数类型。
- class numpy.cdouble(real=0, imag=0)[source]#
由两个双精度浮点数组成的复数类型,与 Python
complex
兼容。- 字符代码:
'D'
- 规范名称:
- 此平台上的别名 (Linux x86_64):
numpy.complex128
: 由2个64位精度浮点数组成的复数类型。
- class numpy.clongdouble[source]#
由两个扩展精度浮点数组成的复数类型。
- 字符代码:
'G'
- 此平台上的别名 (Linux x86_64):
numpy.complex256
: 由2个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 list
,其内容不必是相同的 Python 类型。
对象类型也很特殊,因为包含 object_
项的数组在项访问时不会返回 object_
对象,而是返回数组项所引用的实际对象。
以下数据类型是**灵活的**:它们没有预定义的大小,它们描述的数据在不同的数组中可以有不同的长度。(在字符代码中,#
是一个整数,表示数据类型包含的元素数量。)
- class numpy.flexible[source]#
所有没有预定义长度的标量类型的抽象基类。这些类型的实际大小取决于特定的
numpy.dtype
实例化。
- class numpy.str_[source]#
一个 Unicode 字符串。
此类型会去除尾部的空码点。
>>> s = np.str_("abc\x00") >>> s 'abc'
与内置的
str
不同,这支持 缓冲区协议,将其内容公开为 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 标量。
- 参数:
注释
由于历史原因以及 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'
带大小的别名#
除了(大部分)源自 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
属性。除此之外,它们与数组共享相同的属性
flags 的整数值。 |
|
数组维度元组。 |
|
每个维度中的字节步长元组。 |
|
数组维度数。 |
|
数据起始指针。 |
|
泛型类型中的元素数量。 |
|
一个元素的字节长度。 |
|
与对应数组属性相同的标量属性。 |
|
获取数组数据描述符。 |
|
标量的实部。 |
|
标量的虚部。 |
|
标量的一维视图。 |
|
与对应数组属性相同的标量属性。 |
|
数组协议:Python 端 |
|
数组协议:结构体 |
|
数组优先级。 |
|
标量类型的 __array_wrap__ 实现 |
索引#
另请参见
数组标量可以像0维数组一样索引:如果 x 是一个数组标量,
x[()]
返回数组标量的副本x[...]
返回一个0维的ndarray
x['field-name']
返回字段 field-name 中的数组标量。(x 可以有字段,例如,当它对应于结构化数据类型时。)
方法#
数组标量具有与数组完全相同的方法。这些方法的默认行为是内部将标量转换为等效的0维数组并调用相应的数组方法。此外,数组标量上的数学运算的定义方式是设置相同的硬件标志并用于解释结果,就像 ufunc 一样,因此 ufuncs 使用的错误状态也延续到数组标量上的数学运算。
上述规则的例外情况如下所示
sc.__array__(dtype) 从具有指定 dtype 的标量返回0维数组 |
|
标量类型的 __array_wrap__ 实现 |
|
与对应数组属性相同的标量方法。 |
|
与对应数组属性相同的标量方法。 |
|
pickle 的辅助函数。 |
|
与对应数组属性相同的标量方法。 |
类型提示的实用方法
|
返回 |
定义新类型#
有两种方法可以有效地定义新的数组标量类型(除了从内置标量类型组合结构化类型 dtypes):一种方法是简单地继承 ndarray
并覆盖感兴趣的方法。这在一定程度上有效,但内部某些行为由数组的数据类型固定。要完全自定义数组的数据类型,您需要定义一个新的数据类型,并将其注册到 NumPy。此类新类型只能在 C 中使用 NumPy C-API 定义。