标量#

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。

../_images/dtype-hierarchy.png

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

内置标量类型#

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

某些标量类型与基本 Python 类型基本等效,因此它们也继承自基本 Python 类型和通用数组标量类型。

数组标量类型

相关的 Python 类型

继承?

int_

int

仅限 Python 2

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_ 类型在 Python 3 下**不**继承自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 位精度浮点数类型:符号位 1 位,指数位 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:由两个 32 位精度浮点数组成的复数类型。

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

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

字符代码:

'D'

规范名称:

numpy.cdouble

此平台 (Linux x86_64) 上的别名:

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

class numpy.clongdouble[source]#

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

字符代码:

'G'

此平台 (Linux x86_64) 上的别名:

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

其他类型#

numpy.bool_[source]#

bool 的别名

class numpy.bool[source]#

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

警告

bool 类型不是 int_ 类型的子类(bool 甚至不是数字类型)。这与 Python 的默认实现不同,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 列表,因为它们的内容不必是相同的 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,类数组,类字节,对象

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

dtypedtype,可选

如果提供了新标量的dtype。此dtype必须为“void” dtype(即结构化或非结构化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 priority 属性,其值为NPY_SCALAR_PRIORITY (-1,000,000.0)。它们目前还没有ctypes 属性。除此之外,它们与数组共享相同的属性。

generic.flags

flags 的整数值。

generic.shape

数组维度的元组。

generic.strides

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

generic.ndim

数组维度的数量。

generic.data

指向数据开头的指针。

generic.size

gentype 中元素的数量。

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* 对应于结构化数据类型时,*x* 可以具有字段。)

方法#

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

以下列出了上述规则的例外情况

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。这种新类型只能使用NumPy C-API在 C 中定义。