NumPy中Scalars与Array Scalars概念及相关问题咨询
问题1:这里的Scalars是指单个值吗?
是,Scalars就是指单个独立的数据值,和数组、列表这类可以容纳多个元素的容器类型对应。Python原生的单个int、float、bool、字符串值都属于广义的scalar范畴。
问题2:NumPy提到的24种基础Python类型是什么?和C语言类型是什么关系?
这24种类型是NumPy封装的、可直接在Python代码中调用的标量类型,对应不同位宽、不同取值范围的数值类型,比如np.int8(8位有符号整数)、np.uint16(16位无符号整数)、np.float32(32位单精度浮点数)、np.complex64(64位复数)都属于这类。
它和C语言类型的关系是:这些类型的底层存储逻辑完全匹配C语言的同名原生类型,运算时可以直接调用C层面的数值计算逻辑,相比Python原生的动态类型标量性能高很多。同时NumPy给这些C类型做了Python对象的封装,保证和Python原生语法、原生类型运算时的兼容性。
问题3:Array scalar到底是什么?
Array scalar是你从NumPy数组中提取单个元素时默认返回的类型,比如你执行arr = np.array([1,2,3], dtype=np.int32),再取arr[0],得到的不是Python原生int,而是numpy.int32类型的实例,这就是array scalar。
它本质是带了NumPy dtype属性的单个值,既保留了C类型底层存储的高性能,又实现了ndarray的绝大多数属性和方法——你可以对它调用.dtype、.shape、.ndim这类属性,也可以调用.reshape()、.sum()这类数组方法,表现和0维ndarray几乎一致,唯一的区别就是你提到的描述里提到的:它没有ctype属性(这个属性是ndarray用来获取对应C类型指针的,单个标量不需要这个能力)。
这个设计的核心目的是解决标量和数组混合运算时的类型一致性问题,避免出现Python原生标量和NumPy数组运算时意外触发隐式类型转换的bug。
问题4:实际使用时怎么选择array scalar和ndarray?
绝大多数场景不需要你主动选择,NumPy会自动处理:
- 从数组中取单个元素时会自动返回array scalar,取切片、多元素的时候会自动返回ndarray
- 如果你需要严格控制数值的位宽、避免Python原生动态类型的性能开销,优先用array scalar替代Python原生标量
- 如果你要做批量向量运算、需要用到数组的广播等特性,统一用ndarray即可
如果是单个值的场景,array scalar比0维ndarray更轻量,除了没有ctype属性外二者的表现几乎没有差别,可以直接互换使用。
内容的提问来源于stack exchange,提问作者Tony

