NumPy 数据类型

2021-09-01 10:16 更新

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

NumPy 支持的数值类型比 Python 多得多。本节显示哪些可用,以及如何修改数组的数据类型。 支持的基本类型与 C 中的基本类型密切相关:

Numpy 类型 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 复数,由两个扩展精度浮点数(实部和虚部)表示。

由于其中许多具有平台相关的定义,因此提供了一组固定大小的别名(请参阅大小别名)。

NumPy 数字类型是dtype(数据类型)对象的实例,每个对象都有独特的特征。使用导入 NumPy 后

>>> import numpy as np

在dtypes可作为np.bool_np.float32等等。

上面未列出的高级类型在结构化数组部分进行了探讨。

有 5 种基本数字类型表示布尔值 (bool)、整数 (int)、无符号整数 (uint) 浮点数 (float) 和复数。名称中带有数字的那些表示类型的位大小(即表示内存中的单个值需要多少位)。某些类型(例如int和 intp)具有不同的位大小,具体取决于平台(例如 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 对象。

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

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

请注意,在上面,我们使用Python浮点对象作为 dtype。NumPy的人都知道int是指np.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

2、数组标量

NumPy 通常将数组元素作为数组标量(具有关联 dtype 的标量)返回。数组标量与 Python 标量不同,但在大多数情况下,它们可以互换使用(主要的例外是 v2.x 之前的 Python 版本,其中整数数组标量不能作为列表和元组的索引)。有一些例外,例如当代码需要标量的非常具体的属性时,或者当它专门检查一个值是否是 Python 标量时。通常,通过使用相应的 Python 类型函数(例如intfloatcomplexstrunicode)将数组标量显式转换为 Python 标量,可以轻松解决问题。

使用数组标量的主要优点是它们保留了数组类型(Python 可能没有可用的匹配标量类型,例如int16)。因此,使用数组标量可确保数组和标量之间的行为相同,无论该值是否在数组内。NumPy 标量也有许多与数组相同的方法。

3、溢出错误

当值需要比数据类型中可用的更多内存时,NumPy 数字类型的固定大小可能会导致溢出错误。例如, 对于 64 位整数numpy.power计算正确,但对于 32 位整数给出 1874919424(不正确)。100 ** 8

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

NumPy 和 Python 整数类型的行为在整数溢出方面存在显着差异,并且可能会使期望 NumPy 整数行为类似于 Python 的int. 与 NumPy 不同,Python 的大小int是灵活的。这意味着 Python 整数可以扩展以容纳任何整数并且不会溢出。

NumPy 提供numpy.iinfonumpy.finfo分别验证 NumPy 整数和浮点值的最小值或最大值

>>> 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

4、扩展精度

Python 的浮点数通常是 64 位浮点数,几乎相当于np.float64. 在某些不寻常的情况下,使用更精确的浮点数可能会很有用。这在 numpy 中是否可行取决于硬件和开发环境:具体来说,x86 机器提供具有 80 位精度的硬件浮点,虽然大多数 C 编译器都提供这种 类型,但 MSVC(Windows 构建的标准)使得 等同于(64 位)。NumPy 使编译器可用作(以及 用于复数)。您可以找出 numpy 提供的内容。long double``long double``double``long double``np.longdouble``np.clongdouble``np.finfo(np.longdouble)

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

为了有效的内存对齐,np.longdouble通常用零位填充存储,要么是 96 位要么是 128 位。哪个更高效取决于硬件和开发环境;通常在 32 位系统上它们被填充到 96 位,而在 64 位系统上它们通常被填充到 128 位。np.longdouble填充到系统默认值;np.float96np.float128为需要特定填充的用户提供。尽管有这些名称,np.float96并且 np.float128仅提供与 一样多的精度np.longdouble,即大多数 x86 机器上的 80 位和标准 Windows 版本中的 64 位。

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

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号