标量#

Python 只定义了一种特定数据类别的类型(只有一种整数类型、一种浮点类型等)。这对于不需要关心数据在计算机中如何表示的应用程序来说可能很方便。然而,对于科学计算,通常需要更多的控制。

在 NumPy 中,有 24 种新的基本 Python 类型来描述不同类型的标量。这些类型描述符大多基于 CPython 所使用的 C 语言类型,并包含一些与 Python 类型兼容的其他类型。

数组标量具有与 ndarray 相同的属性和方法。[1] 这允许将数组的单个元素在一定程度上与数组本身同等对待,从而平滑了混合标量和数组操作时产生的粗糙边缘。

数组标量存在于一个数据类型层次结构中(见下图)。可以使用该层次结构进行检测:例如,如果 val 是一个数组标量对象,则 isinstance(val, np.generic) 将返回 True。或者,也可以使用数据类型层次结构的其他成员来确定存在哪种数组标量。因此,例如,如果 val 是一个复数值类型,则 isinstance(val, np.complexfloating) 将返回 True,而如果 val 是一个灵活的字节大小数组类型(str_bytes_void),则 isinstance(val, np.flexible) 将返回 True。

../_images/dtype-hierarchy.png

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

内置标量类型#

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

一些标量类型本质上等同于基本的 Python 类型,因此它们同时继承自这些类型和通用的数组标量类型。

数组标量类型

相关的 Python 类型

是否继承?

int_

int

no

double

float

cdouble

complex

bytes_

bytes

str_

str

bool_

bool

no

datetime64

datetime.datetime

no

timedelta64

datetime.timedelta

no

bool_ 数据类型与 Python 的 bool 非常相似,但它不继承自 bool,因为 Python 的 bool 不允许被继承,并且在 C 级别上,实际布尔数据的长度与 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]#

int8(value=0, /) –

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

字符代码:

'b'

规范名称:

numpy.byte

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

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

class numpy.short[source]#

int16(value=0, /) –

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

字符代码:

'h'

规范名称:

numpy.short

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

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

class numpy.intc[source]#

int32(value=0, /) –

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

字符代码:

'i'

规范名称:

numpy.intc

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

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

class numpy.int_[source]#

int64(value=0, /) –

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

字符代码:

'l'

规范名称:

numpy.long

此平台上的别名 (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(value=0, /)[source]#

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

字符代码:

'q'

无符号整数类型#

class numpy.unsignedinteger[source]#

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

class numpy.ubyte[source]#

uint8(value=0, /) –

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

字符代码:

'B'

规范名称:

numpy.ubyte

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

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

class numpy.ushort[source]#

uint16(value=0, /) –

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

字符代码:

'H'

规范名称:

numpy.ushort

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

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

class numpy.uintc[source]#

uint32(value=0, /) –

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

字符代码:

'I'

规范名称:

numpy.uintc

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

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

class numpy.uint[source]#

uint64(value=0, /) –

无符号有符号整数类型,在 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(value=0, /)[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]#

float16(value=0, /) –

半精度浮点数类型。

字符代码:

'e'

规范名称:

numpy.half

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

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

class numpy.single[source]#

float32(value=0, /) –

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

字符代码:

'f'

规范名称:

numpy.single

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

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

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

float64(value=0, /) –

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

字符代码:

'd'

规范名称:

numpy.double

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

numpy.float64: 64 位精度浮点数类型:符号位,11 位指数,52 位尾数。

class numpy.longdouble(value=0, /)[source]#

扩展精度浮点数类型,兼容 C 的 long double,但不一定兼容 IEEE 754 四倍精度。

字符代码:

'g'

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

numpy.float128: 128 位扩展精度浮点数类型。

复数浮点类型#

class numpy.complexfloating[source]#

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

class numpy.csingle[source]#

complex64(real=0, imag=0, /) –

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

字符代码:

'F'

规范名称:

numpy.csingle

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

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

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

complex128(real=0, imag=0, /) –

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

字符代码:

'D'

规范名称:

numpy.cdouble

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

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

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

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

字符代码:

'G'

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

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

其他类型#

numpy.bool_[source]#

别名: bool

class numpy.bool(value=False, /)[source]#

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

警告

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

字符代码:

'?'

class numpy.datetime64(value=None, *args)[源]#

如果从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(value=0, *args)[源]#

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

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

字符代码:

'm'

class numpy.object_(value=None, /)[源]#

任何Python对象。

字符代码:

'O'

注意

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

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

以下数据类型是**灵活的**:它们没有预定义的长度,并且它们描述的数据在不同数组中可以具有不同的长度。(在字符代码中,#是一个整数,表示数据类型由多少个元素组成。)

class numpy.flexible[源]#

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

class numpy.character[源]#

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

class numpy.bytes_(value='', *args, **kwargs)[源]#

字节字符串。

在数组中使用时,此类型会删除尾随的空字节。

字符代码:

'S'

class numpy.str_(value='', *args, **kwargs)[源]#

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)[源]#

创建一个新的结构化或非结构化的void标量。

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

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

dtypedtype, optional

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

版本1.24中新增。

备注

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

  1. np.void(5)创建一个dtype="V5"标量,其中填充了五个

    \0字节。5可以是Python整数或NumPy整数。

  2. np.void(b"bytes-like")从字节字符串创建一个void标量。

    dtype项的大小将匹配字节字符串的长度,此处为"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。这些更改使类型字符约定与struct模块等其他Python模块更加一致。

固定大小别名#

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

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

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

分别与C99 int8_tint16_tint32_tint64_t兼容。

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

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

分别与C99 uint8_tuint16_tuint32_tuint64_t兼容。

numpy.intp[源]#

用作默认整数和索引的有符号整数类型的别名(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[源]#

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

与C size_t兼容。

字符代码:

'N'

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

numpy.float16[源]#

的别名half

numpy.float32[源]#

的别名single

numpy.float64[源]#

的别名double

numpy.float96#
numpy.float128[源]#

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

numpy.complex64[源]#

的别名csingle

numpy.complex128[源]#

的别名cdouble

numpy.complex192#
numpy.complex256[源]#

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

属性#

数组标量对象具有数组 优先级NPY_SCALAR_PRIORITY(-1,000,000.0)。它们(目前)也没有ctypes属性。否则,它们与数组共享相同的属性

generic.flags

标志的整数值。

generic.shape

数组的维度元组。

generic.strides

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

generic.ndim

数组的维度数。

generic.data

指向数据的起始位置。

generic.size

gentype 中的元素数量。

generic.itemsize

一个元素的长度(以字节为单位)。

generic.base

ndarray.base相同的标量属性。

generic.dtype

获取数组数据描述符。

generic.real

标量的实部。

generic.imag

标量的虚部。

generic.flat

标量的1-D视图。

generic.T

ndarray.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的相同,因此用于ufunc的错误状态也沿用到数组标量上的数学运算。

上述规则的例外情况如下

generic.__array__

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

generic.__array_wrap__

标量类型的__array_wrap__实现

generic.squeeze(/[, axis])

ndarray.squeeze相同的标量方法。

generic.byteswap(/[, inplace])

ndarray.byteswap相同的标量方法。

generic.__reduce__

Pickle的助手。

generic.__setstate__

generic.setflags(*[, write, align, uic])

ndarray.setflags相同的标量方法。

用于类型的实用方法

number.__class_getitem__(item, /)

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

定义新类型#

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