Scalars

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

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

数组标量具有与ndarrays相同的属性和方法。[1]这允许将数组的项目部分地放在与数组相同的基础上,平滑在混合标量和数组操作时产生的粗糙边缘。

数组标量存在于数据类型的层次结构中(见下图)。例如,isinstance(val, np.generic)如果val是数组标量对象将返回True或者,可以使用数据类型层次结构的其他成员来确定存在什么样的数组标量。Thus, for example isinstance(val, np.complexfloating) will return True if val is a complex valued type, while isinstance(val, np.flexible) will return true if val is one of the flexible itemsize array types (string, unicode, void).

../_images/dtype-hierarchy.png

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

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

Built-in scalar types

内置的标量类型如下所示。Along with their (mostly) C-derived names, the integer, float, and complex data-types are also available using a bit-width convention so that an array of the right size can always be ensured (e.g. int8, float64, complex128). 还提供了指向足够大以容纳C指针的整数类型的两个别名(intpuintp)。类似C的名称与字符代码相关联,如表中所示。但是,不建议使用字符代码。

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

数组标量类型 相关Python类型
int_ IntType(仅限Python 2)
float_ FloatType
complex_ ComplexType
str_ StringType
unicode_ UnicodeType

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

警告

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

警告

int_类型不会继承Python3内置的int,因为类型int固定宽度整数类型。

Tip

NumPy中的默认数据类型为float_

在下表中,platform?意味着该类型可能不适用于所有平台。与不同的C或Python类型的兼容性指示:两种类型是兼容的,如果他们的数据是相同的大小,并以相同的方式解释。

布尔:

类型 备注 字符代码
bool_ 兼容:Python bool '?'
bool8 8位  

整数:

byte 兼容:C char 'b'
short 兼容:C短 'h'
intc 兼容:C int 'i'
int_ 兼容:Python int 'l'
longlong 兼容:C长 'q'
intp 足够大以适合指针 'p'
int8 8位  
int16 16位  
int32 32位  
int64 64位  

无符号整数:

ubyte 兼容:C unsigned char 'B'
ushort 兼容:C无符号短 'H'
uintc 兼容:C unsigned int 'I'
uint 兼容:Python int 'L'
ulonglong 兼容:C长 'Q'
uintp 足够大以适合指针 'P'
uint8 8位  
uint16 16位  
uint32 32位  
uint64 64位  

浮点数字:

half   'e'
single 兼容:C float 'f'
double 兼容:C双  
float_ 兼容:Python float 'd'
longfloat 兼容:C长浮点 'g'
float16 16位  
float32 32位  
float64 64位  
float96 96位,平台?  
float128 128位,平台?  

复数浮点数:

csingle   'F'
complex_ 兼容:Python复杂 'D'
clongfloat   'G'
complex64 两个32位浮点数  
complex128 两个64位浮点数  
complex192 两个96位浮点数,平台?  
complex256 两个128位浮点数,平台?  

任何Python对象:

object_ 任何Python对象 'O'

注意

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

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

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

str_ 兼容:Python str 'S#'
unicode_ 兼容:Python unicode 'U#'
void   'V#'

警告

数字兼容性:如果您在数字代码中使用了旧的类型码字符(这是从不推荐的),您将需要将其中的一些更改为新字符。In particular, the needed changes are c -> S1, b -> B, 1 -> b, s -> h, w -> H, and u -> I. 这些更改使类型字符约定与其他Python模块(例如struct模块)更为一致。

Attributes

数组标量对象具有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 基础对象
generic.dtype 获取数组数据描述符
generic.real 实数部分
generic.imag 标量的虚部
generic.flat 标量的1-d视图
generic.T 转置
generic.__array_interface__ 数组协议:Python端
generic.__array_struct__ 数组协议:struct
generic.__array_priority__ 数组优先级。
generic.__array_wrap__ sc .__ array_wrap __(obj)返回数组的标量

Indexing

数组标量可以索引为0维数组:如果x是数组标量,

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

Methods

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

上述规则的例外情况如下:

generic numpy标量类型的基类。
generic.__array__ sc .__ array __(| type)return 0-dim数组
generic.__array_wrap__ sc .__ array_wrap __(obj)返回数组的标量
generic.squeeze 未实现(虚拟属性)
generic.byteswap 未实现(虚拟属性)
generic.__reduce__
generic.__setstate__
generic.setflags 未实现(虚拟属性)

Defining new types

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