标量#

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。

../_images/dtype-hierarchy.png

图:表示数组数据类型的类型对象层次结构。图中未显示 intpuintp 这两种用于索引的整数类型(与 NumPy 2 以来默认整数相同)。#

内置标量类型#

内置标量类型如下所示。类 C 的名称与字符代码相关联,字符代码在其描述中显示。但是,不鼓励使用字符代码。

一些标量类型本质上等同于基本的 Python 类型,因此它们也继承自这些类型以及泛型数组标量类型。

数组标量类型

相关 Python 类型

继承自?

int_

int

double

float

cdouble

complex

bytes_

bytes

str_

str

bool_

bool

datetime64

datetime.datetime

timedelta64

datetime.timedelta

bool_ 数据类型与 Python 的 bool 非常相似,但并未从它继承,因为 Python 的 bool 不允许被继承,而且在 C 级别,实际 bool 数据的大小与 Python 布尔标量不同。

警告

int_ 类型继承自内置的 int,因为 int 类型不是固定宽度的整数类型。

提示

NumPy 中的默认数据类型是 double

class numpy.generic[source]#

NumPy 标量类型的基类。

大多数(所有?)NumPy 标量类型都派生自的类。为了一致性,它公开了与 ndarray 相同的 API,尽管许多相关属性是“只读”或完全不相关。强烈建议用户从此类派生自定义标量类型。

class numpy.number[source]#

所有数字标量类型的抽象基类。

整数类型#

class numpy.integer[source]#

所有整数标量类型的抽象基类。

注意

NumPy 整数类型的行为与 C 整数一致,因此可能受 溢出错误 的影响。

有符号整数类型#

class numpy.signedinteger[source]#

所有有符号整数标量类型的抽象基类。

class numpy.byte[source]#

有符号整数类型,与 C char 兼容。

字符代码

'b'

规范名称

numpy.byte

此平台上的别名 (Linux x86_64)

numpy.int8: 8位有符号整数 (从 -128127)。

class numpy.short[source]#

有符号整数类型,与 C short 兼容。

字符代码

'h'

规范名称

numpy.short

此平台上的别名 (Linux x86_64)

numpy.int16: 16位有符号整数 (从 -32_76832_767)。

class numpy.intc[source]#

有符号整数类型,与 C int 兼容。

字符代码

'i'

规范名称

numpy.intc

此平台上的别名 (Linux x86_64)

numpy.int32: 32位有符号整数 (从 -2_147_483_6482_147_483_647)。

class numpy.int_[source]#

默认有符号整数类型,在64位系统上为64位,在32位系统上为32位。

字符代码

'l'

规范名称

numpy.int_

此平台上的别名 (Linux x86_64)

numpy.int64: 64位有符号整数 (从 -9_223_372_036_854_775_8089_223_372_036_854_775_807)。

此平台上的别名 (Linux x86_64)

numpy.intp: 足够大以适应指针的有符号整数,与 C intptr_t 兼容。

numpy.long[source]#

int_ 的别名

class numpy.longlong[source]#

有符号整数类型,与 C long long 兼容。

字符代码

'q'

无符号整数类型#

class numpy.unsignedinteger[source]#

所有无符号整数标量类型的抽象基类。

class numpy.ubyte[source]#

无符号整数类型,与 C unsigned char 兼容。

字符代码

'B'

规范名称

numpy.ubyte

此平台上的别名 (Linux x86_64)

numpy.uint8: 8位无符号整数 (从 0255)。

class numpy.ushort[source]#

无符号整数类型,与 C unsigned short 兼容。

字符代码

'H'

规范名称

numpy.ushort

此平台上的别名 (Linux x86_64)

numpy.uint16: 16位无符号整数 (从 065_535)。

class numpy.uintc[source]#

无符号整数类型,与 C unsigned int 兼容。

字符代码

'I'

规范名称

numpy.uintc

此平台上的别名 (Linux x86_64)

numpy.uint32: 32位无符号整数 (从 04_294_967_295)。

class numpy.uint[source]#

无符号整数类型,在64位系统上为64位,在32位系统上为32位。

字符代码

'L'

规范名称

numpy.uint

此平台上的别名 (Linux x86_64)

numpy.uint64: 64位无符号整数 (从 018_446_744_073_709_551_615)。

此平台上的别名 (Linux x86_64)

numpy.uintp: 足够大以适应指针的无符号整数,与 C uintptr_t 兼容。

numpy.ulong[source]#

uint 的别名

class numpy.ulonglong[source]#

有符号整数类型,与 C unsigned long long 兼容。

字符代码

'Q'

不精确类型#

class numpy.inexact[source]#

所有数字标量类型的抽象基类,其值在其范围内(可能)存在不精确表示,例如浮点数。

注意

不精确标量使用最少的小数位数打印,通过巧妙的舍入,以区分其值与相同数据类型的其他值。请参阅 format_float_positionalformat_float_scientificunique 参数。

这意味着具有相同二进制值但数据类型精度不同的变量可能会显示不同

>>> 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.floating[source]#

所有浮点标量类型的抽象基类。

class numpy.half[source]#

半精度浮点数类型。

字符代码

'e'

规范名称

numpy.half

此平台上的别名 (Linux x86_64)

numpy.float16: 16位精度浮点数类型:符号位、5位指数、10位尾数。

class numpy.single[source]#

单精度浮点数类型,与 C float 兼容。

字符代码

'f'

规范名称

numpy.single

此平台上的别名 (Linux x86_64)

numpy.float32: 32位精度浮点数类型:符号位、8位指数、23位尾数。

class numpy.double(x=0, /)[source]#

双精度浮点数类型,与 Python float 和 C double 兼容。

字符代码

'd'

规范名称

numpy.double

此平台上的别名 (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.complexfloating[source]#

所有由浮点数组成的复数标量类型的抽象基类。

class numpy.csingle[source]#

由两个单精度浮点数组成的复数类型。

字符代码

'F'

规范名称

numpy.csingle

此平台上的别名 (Linux x86_64)

numpy.complex64: 由2个32位精度浮点数组成的复数类型。

class numpy.cdouble(real=0, imag=0)[source]#

由两个双精度浮点数组成的复数类型,与 Python complex 兼容。

字符代码

'D'

规范名称

numpy.cdouble

此平台上的别名 (Linux x86_64)

numpy.complex128: 由2个64位精度浮点数组成的复数类型。

class numpy.clongdouble[source]#

由两个扩展精度浮点数组成的复数类型。

字符代码

'G'

此平台上的别名 (Linux x86_64)

numpy.complex256: 由2个128位扩展精度浮点数组成的复数类型。

其他类型#

numpy.bool_[source]#

bool 的别名

class numpy.bool[source]#

布尔类型 (True 或 False),存储为字节。

警告

bool 类型不是 int_ 类型的子类(bool 甚至不是数字类型)。这与 Python 默认将 bool 实现为 int 的子类不同。

字符代码

'?'

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'

class numpy.timedelta64[source]#

存储为64位整数的时间差。

有关更多信息,请参见 日期时间和时间差

字符代码

'm'

class numpy.object_[source]#

任何 Python 对象。

字符代码

'O'

注意

实际存储在对象数组中(即,dtype 为 object_ 的数组)的数据是对 Python 对象的引用,而不是对象本身。因此,对象数组的行为更像普通的 Python list,其内容不必是相同的 Python 类型。

对象类型也很特殊,因为包含 object_ 项的数组在项访问时不会返回 object_ 对象,而是返回数组项所引用的实际对象。

以下数据类型是**灵活的**:它们没有预定义的大小,它们描述的数据在不同的数组中可以有不同的长度。(在字符代码中,# 是一个整数,表示数据类型包含的元素数量。)

class numpy.flexible[source]#

所有没有预定义长度的标量类型的抽象基类。这些类型的实际大小取决于特定的 numpy.dtype 实例化。

class numpy.character[source]#

所有字符串标量类型的抽象基类。

class numpy.bytes_[source]#

一个字节字符串。

当在数组中使用时,此类型会去除尾部的空字节。

字符代码

'S'

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 标量。

参数
length_or_dataint, array-like, bytes-like, object

多种含义之一(参见注释)。非结构化 void 的长度或字节数据。或者,当提供了 dtype 时,要存储在新标量中的数据。这可以是一个类数组对象,在这种情况下可能会返回一个数组。

dtypedtype, optional

如果提供,则为新标量的数据类型。此数据类型必须是“void”数据类型(即,结构化或非结构化 void,另请参见 结构化数据类型)。

1.24 版本新增。

注释

由于历史原因以及 void 标量可以表示任意字节数据和结构化 dtype,void 构造函数有三种调用约定

  1. np.void(5) 创建一个 dtype="V5" 标量,填充五个 \0 字节。这里的 5 可以是 Python 或 NumPy 整数。

  2. np.void(b"bytes-like") 从字节字符串创建一个 void 标量。dtype 的 itemsize 将与字节字符串的长度匹配,这里是 "V10"

  3. 当传递 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'

警告

请参阅 字符串类型注意事项

数值兼容性:如果您在 Numeric 代码中使用了旧的类型代码字符(这是不推荐的),您将需要将其中一些更改为新的字符。特别是,需要进行的更改是 c -> S1b -> B1 -> bs -> hw -> Hu -> I。这些更改使类型字符约定与其他 Python 模块(如 struct 模块)更加一致。

带大小的别名#

除了(大部分)源自 C 的名称之外,整数、浮点和复数数据类型也可以使用位宽约定来获取,以便始终确保数组的正确大小。还提供了两个别名(numpy.intpnumpy.uintp),它们指向足够大以容纳 C 指针的整数类型。

numpy.int8[source]#
numpy.int16#
numpy.int32#
numpy.int64#

指定位数的有符号整数类型(numpy.bytenumpy.shortnumpy.intcnumpy.int_numpy.longnumpy.longlong 之一)的别名。

分别与 C99 的 int8_tint16_tint32_tint64_t 兼容。

numpy.uint8[source]#
numpy.uint16#
numpy.uint32#
numpy.uint64#

指定位数的无符号整数类型(numpy.ubytenumpy.ushortnumpy.uintcnumpy.uintnumpy.ulongnumpy.ulonglong 之一)的别名。

分别与 C99 的 uint8_tuint16_tuint32_tuint64_t 兼容。

numpy.intp[source]#

用作默认整数和索引的有符号整数类型(numpy.bytenumpy.shortnumpy.intcnumpy.int_numpy.longnumpy.longlong 之一)的别名。

与 C Py_ssize_t 兼容。

字符代码

'n'

2.0 版本更改:在 NumPy 2 之前,这与指针具有相同的大小。实际上,这几乎总是相同的,但字符代码 'p' 映射到 C intptr_t。字符代码 'n' 在 NumPy 2.0 中添加。

numpy.uintp[source]#

intp 大小相同的无符号整数类型的别名。

与 C size_t 兼容。

字符代码

'N'

2.0 版本更改:在 NumPy 2 之前,这与指针具有相同的大小。实际上,这几乎总是相同的,但字符代码 'P' 映射到 C uintptr_t。字符代码 'N' 在 NumPy 2.0 中添加。

numpy.float16[source]#

half 的别名

numpy.float32[source]#

single 的别名

numpy.float64[source]#

double 的别名

numpy.float96#
numpy.float128[source]#

numpy.longdouble 的别名,以其位大小命名。这些别名的存在取决于平台。

numpy.complex64[source]#

csingle 的别名

numpy.complex128[source]#

cdouble 的别名

numpy.complex192#
numpy.complex256[source]#

numpy.clongdouble 的别名,以其位大小命名。这些别名的存在取决于平台。

属性#

数组标量对象的 array priorityNPY_SCALAR_PRIORITY (-1,000,000.0)。它们也尚未具有 ctypes 属性。除此之外,它们与数组共享相同的属性

generic.flags

flags 的整数值。

generic.shape

数组维度元组。

generic.strides

每个维度中的字节步长元组。

generic.ndim

数组维度数。

generic.data

数据起始指针。

generic.size

泛型类型中的元素数量。

generic.itemsize

一个元素的字节长度。

generic.base

与对应数组属性相同的标量属性。

generic.dtype

获取数组数据描述符。

generic.real

标量的实部。

generic.imag

标量的虚部。

generic.flat

标量的一维视图。

generic.T

与对应数组属性相同的标量属性。

generic.__array_interface__

数组协议:Python 端

generic.__array_struct__

数组协议:结构体

generic.__array_priority__

数组优先级。

generic.__array_wrap__

标量类型的 __array_wrap__ 实现

索引#

数组标量可以像0维数组一样索引:如果 x 是一个数组标量,

  • x[()] 返回数组标量的副本

  • x[...] 返回一个0维的 ndarray

  • x['field-name'] 返回字段 field-name 中的数组标量。(x 可以有字段,例如,当它对应于结构化数据类型时。)

方法#

数组标量具有与数组完全相同的方法。这些方法的默认行为是内部将标量转换为等效的0维数组并调用相应的数组方法。此外,数组标量上的数学运算的定义方式是设置相同的硬件标志并用于解释结果,就像 ufunc 一样,因此 ufuncs 使用的错误状态也延续到数组标量上的数学运算。

上述规则的例外情况如下所示

generic.__array__

sc.__array__(dtype) 从具有指定 dtype 的标量返回0维数组

generic.__array_wrap__

标量类型的 __array_wrap__ 实现

generic.squeeze

与对应数组属性相同的标量方法。

generic.byteswap

与对应数组属性相同的标量方法。

generic.__reduce__

pickle 的辅助函数。

generic.__setstate__

generic.setflags

与对应数组属性相同的标量方法。

类型提示的实用方法

number.__class_getitem__(item, /)

返回 number 类型的参数化包装器。

定义新类型#

有两种方法可以有效地定义新的数组标量类型(除了从内置标量类型组合结构化类型 dtypes):一种方法是简单地继承 ndarray 并覆盖感兴趣的方法。这在一定程度上有效,但内部某些行为由数组的数据类型固定。要完全自定义数组的数据类型,您需要定义一个新的数据类型,并将其注册到 NumPy。此类新类型只能在 C 中使用 NumPy C-API 定义。