数据类型

数组类型和类型之间的转换

numpy支持比python更多的数值类型。本节显示哪些可用,以及如何修改数组的数据类型。

支持的基元类型与C中的基元类型紧密相连:

纽曼型

C型

描述

numpy.bool_

bool

存储为字节的布尔值(真或假)

numpy.byte

signed char

平台已定义

numpy.ubyte

unsigned char

平台已定义

numpy.short

short

平台已定义

numpy.ushort

unsigned short

平台已定义

numpy.intc

int

平台已定义

numpy.uintc

unsigned int

平台已定义

numpy.int_

long

平台已定义

numpy.uint

unsigned long

平台已定义

numpy.longlong

long long

平台已定义

numpy.ulonglong

unsigned long long

平台已定义

numpy.half / numpy.float16

半精度浮点:符号位,5位指数,10位尾数

numpy.single

float

平台定义的单精度浮点:典型的符号位、8位指数、23位尾数

numpy.double

double

平台定义的双精度浮点:典型的符号位、11位指数、52位尾数。

numpy.longdouble

long double

平台定义的扩展精度浮点

numpy.csingle

float complex

复数,由两个单精度浮点数(实部和虚部)表示

numpy.cdouble

double complex

复数,由两个双精度浮点数(实部和虚部)表示。

numpy.clongdouble

long double complex

复数,由两个扩展的精度浮点(实部和虚部)表示。

由于其中许多定义依赖于平台,因此提供了一组固定大小的别名:

纽曼型

C型

描述

numpy.int8

int8_t

字节(-128到127)

numpy.int16

int16_t

整数(-32768到32767)

numpy.int32

int32_t

整数(-2147483648到2147483647)

numpy.int64

int64_t

整数(-9223372036854775808到9223372036854775807)

numpy.uint8

uint8_t

无符号整数(0到255)

numpy.uint16

uint16_t

无符号整数(0到65535)

numpy.uint32

uint32_t

无符号整数(0到4294967295)

numpy.uint64

uint64_t

无符号整数(0到18446744073709551615)

numpy.intp

intptr_t

用于索引的整数,通常与 ssize_t

numpy.uintp

uintptr_t

足以容纳指针的整数

numpy.float32

float

numpy.float64 / numpy.float_

double

请注意,这与内置python的精度相匹配 float .

numpy.complex64

float complex

复数,由两个32位浮点(实部和虚部)表示

numpy.complex128 / numpy.complex_

double complex

请注意,这与内置python的精度相匹配 complex .

numpy数字类型是 dtype (数据类型)对象,每个对象都具有独特的特性。一旦你导入了numpy

>>> import numpy as np

数据类型可用为 np.bool_np.float32 等。

上表中未列出的高级类型在第节中进行了探讨。 结构化数组 .

有5种基本的数字类型代表布尔(bool)、整数(int)、无符号整数(uint)、浮点(float)和复数。名称中带有数字的表示类型的位大小(即表示内存中单个值需要多少位)。一些类型,例如 intintp ,具有不同的位大小,具体取决于平台(例如32位与64位机器)。在与原始内存寻址的低级代码(如C或Fortran)进行接口时,应该考虑到这一点。

数据类型可以用作将python数字转换为数组标量的函数(有关说明,请参阅数组标量部分)、将数字的python序列转换为该类型的数组或用作许多numpy函数或方法接受的dtype关键字的参数。一些例子:

>>> import numpy as np
>>> x = np.float32(1.0)
>>> x
1.0
>>> y = np.int_([1,2,4])
>>> y
array([1, 2, 4])
>>> z = np.arange(3, dtype=np.uint8)
>>> z
array([0, 1, 2], dtype=uint8)

数组类型也可以由字符代码引用,主要是为了保持与旧包(如numeric)的向后兼容性。一些文档可能仍然引用这些内容,例如:

>>> np.array([1, 2, 3], dtype='f')
array([ 1.,  2.,  3.], dtype=float32)

我们建议改用dtype对象。

要转换数组的类型,请使用.as type()方法(首选)或类型本身作为函数。例如:

>>> z.astype(float)                 
array([  0.,  1.,  2.])
>>> np.int8(z)
array([0, 1, 2], dtype=int8)

请注意,上面我们使用 Python 将对象作为数据类型浮动。NumPy 知道 intnp.int_bool 方法 np.bool_ ,那 floatnp.float_complexnp.complex_ . 其他数据类型没有对应的python。

要确定数组的类型,请查看dtype属性:

>>> z.dtype
dtype('uint8')

DTYPE对象还包含有关类型的信息,例如其位宽度和字节顺序。数据类型还可以间接用于查询该类型的属性,例如它是否为整数::

>>> d = np.dtype(int)
>>> d
dtype('int32')

>>> np.issubdtype(d, np.integer)
True

>>> np.issubdtype(d, np.floating)
False

数组标量

numpy通常返回数组元素作为数组标量(一个带有关联数据类型的标量)。数组scalar与python scalar不同,但在大多数情况下,它们可以互换使用(主要的例外是对于早于v2.x的python版本,其中整数数组scalar不能用作列表和元组的索引)。有一些例外,例如当代码需要标量的非常特定的属性,或者当它专门检查一个值是否是python标量时。通常,通过使用相应的python类型函数(例如, intfloatcomplexstrunicode

使用数组标量的主要优点是它们保留了数组类型(python可能没有匹配的标量类型可用,例如 int16 )因此,使用数组标量可以确保数组和标量之间的行为相同,而不管值是否在数组中。numpy scalar也有许多与数组相同的方法。

溢出错误

当值需要的内存超过数据类型中的可用内存时,NumPy numeric类型的固定大小可能会导致溢出错误。例如, numpy.power 评估 100 * 10 ** 8 对64位整数正确,但对32位整数给出1874919424(不正确)。

>>> np.power(100, 8, dtype=np.int64)
10000000000000000
>>> np.power(100, 8, dtype=np.int32)
1874919424

对于整数溢出,NumPy和Python integer类型的行为有很大的不同,这可能会使希望NumPy integer的行为类似于Python的行为的用户感到困惑 int . 与NumPy不同,Python的 int 是灵活的。这意味着Python整数可以扩展以容纳任何整数,并且不会溢出。

NumPy提供 numpy.iinfonumpy.finfo 要分别验证NumPy integer和浮点值的最小值或最大值,请执行以下操作:

>>> np.iinfo(int) # Bounds of the default integer on this system.
iinfo(min=-9223372036854775808, max=9223372036854775807, dtype=int64)
>>> np.iinfo(np.int32) # Bounds of a 32-bit integer
iinfo(min=-2147483648, max=2147483647, dtype=int32)
>>> np.iinfo(np.int64) # Bounds of a 64-bit integer
iinfo(min=-9223372036854775808, max=9223372036854775807, dtype=int64)

如果64位整数仍然太小,结果可能会转换为浮点数。浮点数提供了更大但不精确的可能值范围。

>>> np.power(100, 100, dtype=np.int64) # Incorrect even with 64-bit int
0
>>> np.power(100, 100, dtype=np.float64)
1e+200

扩展精度

python的浮点数通常是64位浮点数,几乎相当于 np.float64 . 在某些特殊情况下,使用精度更高的浮点数可能很有用。这在numpy中是否可行取决于硬件和开发环境:特别是,x86机器提供80位精度的硬件浮点,而大多数C编译器提供这一点作为它们的 long double 类型,msvc(Windows版本的标准)使 long double 相同的 double (64位)。numpy生成编译器的 long double 可作为 np.longdouble (和 np.clongdouble 对于复数)。你可以找到你的 NumPy 在 np.finfo(np.longdouble) 中提供了什么。

NumPy不提供比C更精确的数据类型 long double \;尤其是128位IEEE四精度数据类型(FORTRAN的 REAL*16 \)不可用。

为了有效地对齐内存, np.longdouble 通常用零位(96位或128位)填充存储。哪个更有效取决于硬件和开发环境;通常在32位系统上,它们被填充到96位,而在64位系统上,它们通常被填充到128位。 np.longdouble 填充为系统默认值; np.float96np.float128 为需要特定填充的用户提供。尽管有名字, np.float96np.float128 提供的精度与 np.longdouble 也就是说,在大多数x86计算机上为80位,在标准Windows版本中为64位。

被警告即使 np.longdouble 提供比python更高的精度 float ,很容易失去额外的精度,因为python经常强制值通过 float . 例如, % 格式化运算符要求将其参数转换为标准的python类型,因此即使请求了许多小数位,也无法保留扩展精度。使用值测试代码可能很有用 1 + np.finfo(np.longdouble).eps .