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