当前位置: 首页 > ds >正文

NumPy 2.x 完全指南【二十二】数组标量

文章目录

  • 1. 标量(Scalar )
  • 2. 数组标量(Array Scalar)
  • 3. 标量类型
    • 3.1 基类
      • 3.1.1 generic
      • 3.1.2 number
      • 3.1.3 flexible
    • 3.2 整数类型
      • 3.2.1 有符号整数
      • 3.2.2 无符号整数
    • 3.3 不精确类型
      • 3.3.1 浮点数
      • 3.3.2 复数
    • 3.4 其他类型
      • 3.4.1 布尔类型
      • 3.4.2 日期时间与时间差
      • 3.4.3 对象类型
      • 3.4.4 灵活类型(无预定义长度)
  • 4. 对象属性
  • 5. 对象方法
  • 6. 索引

1. 标量(Scalar )

Scalar [ˈskeɪlər] 作为名词时翻译为数量、标量。

定义:只有大小,没有方向的量

在数学中,一般称为数量,当我们还在蹒跚学步、咿咿呀呀的时候,其实就已经开始学习最简单的标量,例如数字 123 。在初中物理中,我们也学过很多标量类型的物理量,比如质量、密度、温度等等。

标量在计算时遵循一般的代数运算法则,这些肯定也是大家最熟悉的了,比如小学的加法、减法、乘法、除法四则运算,初中学过的指数运算、比较运算、绝对值、根运算、对数运算以及模运算等。

在计算机领域中,标量通常用于表示简单的数据类型,如整数、浮点数和布尔值等,比如在 Python 中,intfloat 都是标量类型:

x = 5 # 整数,标量
y = 3.14 # 浮点数,标量
z = True # 布尔值,标量

2. 数组标量(Array Scalar)

Python 只定义了特定数据类的单一类型,在一般的编程场景中,不需要关注数据如何在计算机中表示,但是在在科学计算中,通常需要更多的控制。

NumPy 在基础 Python 类型的基础上提供了 24 种新的不同类型的标量,这些类型描述符大多基于 C 语言中的类型(CPython 是用 C 语言编写的),并且有几个类型与 Python 类型兼容。

从多维数组 (ndarray) 中提取的单个元素时,返回的是数组标量(array scalars),不是普通的 Python 数值类型,而是具有与 ndarray 相同的属性和方法的特殊对象,但数组标量是不可变的,因此不能设置任何数组标量的属性,这种设计使得标量和数组之间的操作更加一致。

数据类型的层次结构如下:
在这里插入图片描述

图示说明:

  • 所有数组标量都继承自基类 np.generic
  • 数值类数组标量(如整数、浮点数、复数)进一步继承自 np.number,并分为更细的子类。
  • 非数值类型(如字符串、字节、自定义结构)属于 np.flexible 分支,表示可变长度的数据类型。
  • 布尔值(np.bool_)、日期时间(np.datetime64np.timedelta64)、对象类型(np.object_)等特殊类型也有自己的层次位置。
  • 未显示的是两个整数类型 intpuintp,它们用于索引(与自 NumPy 2 以来的默认整数相同)。

某些标量类型本质上等同于 Python 的基础类型,因此既继承自它们,也继承自通用数组标量类型(np.generic):

数组标量类型关联的 Python 类型是否继承?
int_int仅限 Python 2
doublefloat
cdoublecomplex
bytes_bytes
str_str
bool_bool
datetime64datetime.datetime
timedelta64datetime.timedelta

示例 1 ,提取单个元素得到的对象是一个数组标量,支持与 ndarray 相同的属性和方法:

arr = np.array([1, 2, 3], dtype=np.int32)
scalar = arr[0]  # 数组标量 np.int32print(scalar.dtype)  # 输出: int32
print(scalar.shape)  # 输出: ()
print(scalar.item())  # 输出: 1 (Python int)

注意事项:

  • bool_ 数据类型与 Pythonbool 非常相似,但不继承自 bool,因为 Pythonbool 不允许继承,并且在 C 语言层次上,它们的大小不同。
  • int_Python 3 中不再继承自 intint 是任意精度整数(支持大整数),而 NumPyint_ 是固定宽度的。
  • 当创建 NumPy 数组时,若未指定 dtype,浮点数默认使用 float64(即 double),整数数组的默认类型为 int_(平台相关,通常为 int32int64)。

3. 标量类型

3.1 基类

3.1.1 generic

numpy.generic:所有 NumPy 标量类型的基类。

类定义:

class generic(_ArrayOrScalarCommon, Generic[_ItemT_co]):@abstractmethoddef __init__(self, *args: Any, **kwargs: Any) -> None: ...def __hash__(self) -> int: ...# ......

示例 1 ,通过 isinstance(val, np.generic),可以快速判断一个对象是否为 Numpy 数组标量:

val = np.int32(5)
print(isinstance(val, np.generic))  # 输出: Trueval_python = 5
print(isinstance(val_python, np.generic))  # 输出: False

3.1.2 number

numpy.number:所有数值标量类型(整数、浮点数、复数)的抽象基类。

类定义:

class number(generic[_NumberItemT_co], Generic[_NBit, _NumberItemT_co]):@abstractmethoddef __init__(self, value: _NumberItemT_co, /) -> None: ...def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...def __neg__(self) -> Self: ...def __pos__(self) -> Self: ...def __abs__(self) -> Self: ...# ......

示例 1 ,通过 isinstance(val, np.number),可以快速判断一个对象是否为 Numpy 数值标量类型:

val_int = np.int32(5)
val_float = np.float64(3.14)print(isinstance(val_int, np.number))   # True
print(isinstance(val_float, np.number)) # True

3.1.3 flexible

numpy.flexible:可变长度标量类型的抽象基类。

类定义:

class flexible(_RealMixin, generic[_FlexibleItemT_co], Generic[_FlexibleItemT_co]): 

子类:

  • numpy.character
    • numpy.str_:字符串。
    • numpy.bytes_:字节类型。
  • numpy.void:自定义结构或原始字节数据。

示例 1 , numpy.dtype 参数指定大小:

# 定义长度为 10 的 Unicode 字符串类型(每个字符占 4 字节)
dtype_str = np.dtype('U10')  # 总大小 = 10 * 4 = 40 字节
arr_str = np.array(['hello', 'world'], dtype=dtype_str)# 定义长度为 5 的字节字符串类型(固定 5 字节)
dtype_bytes = np.dtype('S5')  # 总大小 = 5 字节
arr_bytes = np.array([b'12345', b'abcde'], dtype=dtype_bytes)

3.2 整数类型

抽象基类:

  • numpy.signedinteger:所有有符号整数标量类型的抽象基类。
  • numpy.unsignedinteger:所有无符号整数标量类型的抽象基类。

3.2.1 有符号整数

NumPy 类型字符代码规范名称平台别名(Linux x86_64)描述
numpy.byte'b'numpy.bytenumpy.int88 位有符号整数(C char),范围:-128 到 127
numpy.short'h'numpy.shortnumpy.int1616 位有符号整数(C short),范围:-32,768 到 32,767
numpy.intc'i'numpy.intcnumpy.int3232 位有符号整数(C int),范围:-2,147,483,648 到 2,147,483,647
numpy.int_'l'numpy.int_numpy.int64
numpy.intp
默认有符号整数类型(64 位系统为 64 位,32 位系统为 32 位)
兼容 C intptr_t(指针大小整数)
numpy.longnumpy.int_numpy.int_ 的别名
numpy.longlong'q'numpy.longlong64 位有符号整数(C long long),范围:-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807

3.2.2 无符号整数

NumPy 类型字符代码规范名称平台别名(Linux x86_64)描述
numpy.ubyte'B'numpy.ubytenumpy.uint88 位无符号整数(C unsigned char),范围:0 到 255
numpy.ushort'H'numpy.ushortnumpy.uint1616 位无符号整数(C unsigned short),范围:0 到 65,535
numpy.uintc'I'numpy.uintcnumpy.uint3232 位无符号整数(C unsigned int),范围:0 到 4,294,967,295
numpy.uint'L'numpy.uintnumpy.uint64
numpy.uintp
默认无符号整数类型(64 位系统为 64 位,32 位系统为 32 位)
兼容 C uintptr_t(指针大小无符号整数)
numpy.ulongnumpy.uintnumpy.uint 的别名
numpy.ulonglong'Q'numpy.ulonglong64 位无符号整数(C unsigned long long),范围:0 到 18,446,744,073,709,551,615

3.3 不精确类型

抽象基类:

  • numpy.inexact:所有不精确数值标量类型(浮点数、复数)的抽象基类。
    • numpy.floating:所有浮点数标量类型的抽象基类。
    • numpy.complexfloating:所有复数标量类型(由浮点数组成)的抽象基类。

3.3.1 浮点数

NumPy 类型字符代码规范名称平台别名(Linux x86_64)描述
numpy.half'e'numpy.halfnumpy.float1616 位半精度浮点数(1 位符号,5 位指数,10 位尾数)。
numpy.single'f'numpy.singlenumpy.float3232 位单精度浮点数(1 位符号,8 位指数,23 位尾数),兼容 C float
numpy.double'd'numpy.doublenumpy.float6464 位双精度浮点数(1 位符号,11 位指数,52 位尾数),兼容 Python float 和 C double
numpy.longdouble'g'numpy.longdoublenumpy.float128扩展精度浮点数(兼容 C long double,但未必符合 IEEE 754 四倍精度)。

3.3.2 复数

NumPy 类型字符代码规范名称平台别名(Linux x86_64)描述
numpy.csingle'F'numpy.csinglenumpy.complex64复数类型,由两个 float32 组成。
numpy.cdouble'D'numpy.cdoublenumpy.complex128复数类型,由两个 float64 组成,兼容 Python complex
numpy.clongdouble'G'numpy.clongdoublenumpy.complex256复数类型,由两个 float128 组成。

3.4 其他类型

3.4.1 布尔类型

NumPy 类型字符代码规范名称描述
numpy.bool_'?'numpy.bool布尔类型(True/False),存储为字节。警告bool_ 不是 int_ 的子类。

3.4.2 日期时间与时间差

NumPy 类型字符代码描述
numpy.datetime64'M'表示时间戳(从 1970-01-01T00:00:00 的偏移量或 ISO 8601 字符串)。警告:解析字符串时忽略时区。
numpy.timedelta64'm'时间差类型,存储为 64 位整数。

3.4.3 对象类型

NumPy 类型字符代码描述
numpy.object_'O'任意 Python 对象。注意:存储的是对象引用,而非对象本身。

3.4.4 灵活类型(无预定义长度)

NumPy 类型字符代码规范名称描述
numpy.flexible所有无预定义长度的标量类型的抽象基类(如字符串、字节、自定义结构)。
numpy.character所有字符串标量类型的抽象基类。
numpy.bytes_'S'numpy.bytes_字节字符串类型(自动去除末尾空字节)。
numpy.str_'U'numpy.str_Unicode 字符串类型(自动去除末尾空字符)。注意:支持缓冲协议,内部存储为 UCS4
numpy.void'V'numpy.void结构化或非结构化二进制数据,需指定长度或数据。

4. 对象属性

数组标量数组对象与数组共享大部分属性,但可能表现不同,在逻辑上行为有所区别:

属性描述标量的具体表现
flags整数值,表示数据的存储属性(如是否可写、连续性)。不可写:在标量中 flags 直接返回整数,如 WRITEABLE=False
shape数组维度的元组。标量是 0 维,返回空元组:()
strides每个维度中步长的字节数(用于连续内存访问)。标量是 0 维,返回空元组:()
ndim数组的维度数量。0(标量无维度)
data指向元素数据缓冲区的指针(Python 字节对象形式)。存在,但实际用途有限(如 np.int32(5).data 返回包含单个值的缓冲区)。
size数组或标量中元素的总数。1(标量总是单元素)
itemsize单个元素占用的字节数(如 int32 为 4 字节)。np.float64(3.14).itemsize 返回 8
base根据数组是否共享内存,指向原始对象。标量是独立对象,返回 None
dtype数组或标量的数据类型描述符。返回对应的 dtype 对象(如 np.float32 对应 float32)。
real / imag复数标量的实部和虚部;非复数标量返回 self0np.complex128(3+4j).real 返回 3.0.imag 返回 4.0
flat一维迭代器视图。对标量无意义,但仍返回一个生成器(仅能迭代一次,如 next(x.flat))。
T转置(对标量而言,没有变化)。返回标量自身。
__array_interface__Python 层级接口,定义与外部库交互的协议(如数据类型、形状、数据指针)。np.int16(5).__array_interface__ 包含键如 'shape', 'typestr'
__array_struct__C 语言层级接口(PyArrayInterface结构体),用于直接内存操作。标量支持该接口,便于底层操作。
__array_priority__控制混合运算时的优先级(值越高,优先级越高)。标量的优先级为 -1,000,000.0,低于数组(默认 0),因此标量运算结果被广播为数组。例如:np.array([2]) + 3 结果为数组,而非标量。
__array_wrap__自定义对象在运算后的包装行为(可子类化标量时覆盖此方法)。默认返回标量类型。

示例:

s = np.float64(3.14)  # 标量print("Shape:", s.shape)        # 输出: ()
print("Data:", s.data)          # 输出: <memory at ...>
print("Size:", s.size)          # 输出: 1
print("Dtype:", s.dtype)        # 输出: float64
print("Flags:", s.flags)        # 输出: 不可写(如 WRITEABLE=False)
print("Real/Imag:", s.real, s.imag) # 输出: 3.14 0.0

5. 对象方法

数组标量的方法与 ndarray 对象的方法完全一致,但其默认行为是将标量隐式转换为 0 维数组后调用数组方法。

通用方法:

方法标量行为示例
squeeze()对标量无实际效果(标量本身就是 0 维)。np.int32(5).squeeze() 返回自身。
byteswap()返回字节顺序交换后的新标量(标量不可变)。np.int16(0x1234).byteswap()0x3412(新标量)。
setflags()对标量无效(标量数据不可写)。调用会忽略或引发警告。

特殊方法:

方法标量行为用途
__array__(dtype)将标量转换为指定 dtype 的 0 维数组。用于类型强制转换:s.__array__('float32')float32 数组。
__array_wrap__()控制运算后返回结果的类型(默认返回标量类型)。子类化标量时覆盖此方法可自定义运算结果类型。
__reduce__()序列化(Pickle)支持,存储重建标量所需的信息。pickle.dumps(np.float64(3.14)) 依赖此方法。
__setstate__()反序列化时恢复标量状态。pickle.loads(...) 时调用。

类型参数化方法:

方法行为示例
__class_getitem__(item)返回参数化的类型包装器(用于泛型类型注解)。np.float32.__class_getitem__('DType') → 类型提示元数据。

与数组方法的区别:

方法/属性数组行为标量行为
resize()修改数组形状。不可用(标量不可变)。
fill()填充数组元素。不可用(标量不可变)。
view(dtype)返回数据视图(共享内存)。返回新标量(因标量不可共享内存)。
__setitem__支持索引赋值。不可用(标量不可变)。

6. 索引

数组标量索引的三种使用方式:

  • x[()]:获取标量的副本。
  • x[...]:转换为 0 维数组
  • x['field-name']:访问结构化字段

示例 1 ,x[()] 将数组标量视为 0 维数组,通过空元组 () 索引访问其值,返回一个副本:

s = np.int32(5)  # 标量
copy_s = s[()]   # 返回 int32(5) 的副本
copy_s = 10       # 修改副本
print(s)          # 输出: 5(原标量未改变)

示例 2 ,使用省略号 ... 索引,将标量转换为 0 维数组(ndarray 对象):

s = np.float64(3.14)
arr = s[...]      # 转换为 0 维数组
print(type(arr))  # 输出: <class 'numpy.ndarray'>
print(arr)        # 输出: array(3.14)

示例 3 ,当标量对应结构化数据类型(structured dtype)时,通过字段名访问其字段值:

# 定义结构化数据类型
dt = np.dtype([('x', 'i4'), ('y', 'f4')])
s = np.array((5, 3.14), dtype=dt)[()]  # 创建结构化标量print(s['x'])  # 输出: 5(int32 标量)
print(s['y'])  # 输出: 3.14(float32 标量)
http://www.xdnf.cn/news/9862.html

相关文章:

  • Socket网络编程
  • Vue3 + Element Plus 实现树形结构的“单选 + 只选叶子节点 + 默认选中第一个子节点”
  • 微内核与宏内核有什么区别(GAI)
  • laya3的2d相机与2d区域
  • 2025.05.28-华为暑期实习第二题-200分
  • 尝鲜纯血鸿蒙,华为国际版本暂时不支持升级。如mateX6 国际版?为什么不支持?什么时候支持?
  • spark shuffle的分区支持动态调整,而hive不支持
  • Oracle MOVE ONLINE 实现原理
  • Java求职者面试题详解:计算机网络、操作系统、设计模式与数据结构
  • VR 电缆故障测试系统:技术革新​
  • 数控技术应用理实一体化平台VR实训系统
  • python中使用高并发分布式队列库celery的那些坑
  • 深入解析Java8核心新特性(Optional、新的日期时间API、接口增强)
  • Android AIDL Hal最低保证出现的问题
  • CSS基础巩固-选择
  • 【大模型02】Deepseek使用和prompt工程
  • PH热榜 | 2025-05-29
  • leetcode235.二叉搜索树的最近公共祖先:迭代法利用有序性高效寻根
  • 【音频处理】java流式调用ffmpeg命令
  • 《Python 应用中的蓝绿部署与滚动更新:持续集成中的实践与优化》
  • Java设计模式从基础到实际运用
  • 【redis实战篇】第六天
  • 一根网线连接两台电脑组建局域网
  • 不起火,不爆炸,高速摄像机、数字图像相关DIC技术在动力电池新国标安全性能测试中的应用
  • 代码随想录算法训练营第60期第五十一天打卡
  • R3GAN训练自己的数据集
  • Java中float和double的区别与用法解析
  • 华为OD机试真题——阿里巴巴找黄金宝箱(III)(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
  • WPF 全局加载界面、多界面实现渐变过渡效果
  • DexWild:野外机器人策略的灵巧人机交互