标量

Python只定义了一种特定数据类(只有一种整数类型,一种浮点类型等)。 这在不需要 关注数据在计算机中表示的所有方式的应用中是方便的。 然而,对于科学计算,通常需要控制更多。

在NumPy中,有24种新的基本Python类型来描述不同类型的标量。 这些类型描述符主要基 于CPython编写的C语言中可用的类型,其他几种类型与Python的类型兼容。

数组标量与 ndarray 具有相同的属性和方法。[1]这使得人们可以在与数组相 同的基础上处理数组中的部分项,从而平滑混合标量和数组操作时产生的粗糙边缘。

数组标量存在于数据类型的层次结构中(请参见下图)。 可以使用层次结构检测它们,例如: 如果 val 是数组标量对象,则 isinstance(val, np.generic) 将返回 True 。 或者,可以使用数据类型层次结构的其他成员来确定存在何种类型的数组标量。 因此,例如, 如果 val 是复数类型,则 isinstance(val, np.complexfloating) 将返回 True ,而如果 val 是灵活的itemsize数组类型之一,则 isinstance(val, np.flexible) 将返回`True` (string, unicode, void).

../_images/dtype-hierarchy.png

Figure: 表示数组数据类型的类型对象的层次结构。未显示的是两个整数类型 intpuintp ,它们只是指向保存平台指针的整数类型。所有的数字类型也可以使用位宽名称来获得。

[1]但是,数组标量是不可变的,因此没有一个数组标量属性是可设置的。

内置标量类型

内置标量类型如下所示。 除了它们(大多数)C派生的名称,整数,浮点和复数数据类型也可以使用位宽约定, 以便始终可以确保正确大小的数组(例 int8, float64,:class:complex128) 还提供了指向足够大以容纳C指针的整数类型的两个别名( intp and uintp )。 类似C的名称与字符代码相关联,如表中所示。 但是,不鼓励使用字符代码。

一些标量类型基本上等同于基本的Python类型,因此从它们以及通用数组标量类型继承:

数组标量类型 相关的Python类型
int_ IntType (Python 2 only)
float_ FloatType
complex_ ComplexType
bytes_ BytesType
unicode_ UnicodeType

bool_ 数据类型与Python BooleanType 非常相似,但不会从它继承, 因为Python的BooleanType不允许自己继承,而在C级别的大小 实际的bool数据与Python布尔标量不同。

警告

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

警告

int_ 类型不从Python 3中的int内置继承,因为 int 类型不再是固定宽度的整数类型。

小技巧

NumPy中的默认数据类型是 float_

在下表中,platform? 表示该类型可能并非在所有平台上都可用。 指出了与不同C或Python类型的兼容性: 如果两种类型的数据具有相同的大小并以相同的方式解释,则它们是兼容的。

布尔值:

Type Remarks Character code
bool_ 兼容: Python bool '?'
bool8 8 bits  

整形:

byte 兼容: C char 'b'
short 兼容: C short 'h'
intc 兼容: C int 'i'
int_ 兼容: Python int 'l'
longlong 兼容: C long long 'q'
intp 大到可用于指针 'p'
int8 8 bits  
int16 16 bits  
int32 32 bits  
int64 64 bits  

无符号整形:

ubyte 兼容: C unsigned char 'B'
ushort 兼容: C unsigned short 'H'
uintc 兼容: C unsigned int 'I'
uint 兼容: Python int 'L'
ulonglong 兼容: C long long 'Q'
uintp 大到可用于指针 'P'
uint8 8 bits  
uint16 16 bits  
uint32 32 bits  
uint64 64 bits  

浮点类型:

half   'e'
single 兼容: C float 'f'
double 兼容: C double  
float_ 兼容: Python float 'd'
longfloat 兼容: C long float 'g'
float16 16 bits  
float32 32 bits  
float64 64 bits  
float96 96 bits, platform?  
float128 128 bits, platform?  

复数类型:

csingle   'F'
complex_ 兼容: Python complex 'D'
clongfloat   'G'
complex64 two 32-bit floats  
complex128 two 64-bit floats  
complex192 two 96-bit floats, platform?  
complex256 two 128-bit floats, platform?  

所有Python对象:

object_ 所有Python对象: 'O'

注解

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

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

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

bytes_ 兼容: Python bytes 'S#'
unicode_ 兼容: Python unicode/str 'U#'
void   'V#'

警告

请参阅 字符串类型 的解释

数字兼容性:如果您在数字代码中使用了旧的类型代码字符(不推荐这么做), 则需要将其中一些更改为新字符。 特别是,所需的更改是 c -> S1, b -> B, 1 -> b, s -> h, w ->H, and u -> I 这些更改使类型字符约定与其他Python更加一致 诸如 struct 模块之类的模块。

属性

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

generic.flags integer value of flags
generic.shape tuple of array dimensions
generic.strides tuple of bytes steps in each dimension
generic.ndim number of array dimensions
generic.data pointer to start of data
generic.size number of elements in the gentype
generic.itemsize length of one element in bytes
generic.base base object
generic.dtype get array data-descriptor
generic.real real part of scalar
generic.imag imaginary part of scalar
generic.flat a 1-d view of scalar
generic.T transpose
generic.__array_interface__ Array protocol: Python side
generic.__array_struct__ Array protocol: struct
generic.__array_priority__ Array priority.
generic.__array_wrap__ sc.__array_wrap__(obj) return scalar from array

索引

数组标量可以像0维数组一样索引:如果x是数组标量

  • x[()] 返回数组标量的副本
  • x[...] 返回一个0维的 ndarray
  • x['field-name'] 返回字段 field-name 中的数组标量.(x 可以包含字段, 当它对应于结构化数据类型时.)

方法

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

下列的规则例外:

generic Base class for numpy scalar types.
generic.__array__ sc.__array__(dtype) return 0-dim array from scalar with specified dtype
generic.__array_wrap__ sc.__array_wrap__(obj) return scalar from array
generic.squeeze Not implemented (virtual attribute)
generic.byteswap Not implemented (virtual attribute)
generic.__reduce__ helper for pickle
generic.__setstate__
generic.setflags Not implemented (virtual attribute)

定义新类型

有两种方法可以有效地定义新的数组标量类型(除了从内置标量类型组合结构化类型 dtypes 一种方法是简单地子类化 ndarray 并覆盖感兴趣的方法。 这将在一定程度上起作用, 但内部某些行为由数组的数据类型修复。 要完全自定义数组的数据类型,您需要定义新的数据类型, 并使用NumPy进行注册。 这些新类型只能使用 NumPy C-API 在C中定义。