NumPy 教程

NumPy 首页 NumPy 简介 NumPy 环境

数组

NumPy Ndarray 对象 NumPy 数据类型

创建和操作数组

NumPy 数组创建例程 NumPy 数组操作 NumPy 基于现有数据创建数组 NumPy 基于数值范围创建数组 NumPy 数组迭代 NumPy 重塑数组 NumPy 连接数组 NumPy 堆叠数组 NumPy 拆分数组 NumPy 展平数组 NumPy 转置数组

索引与切片

NumPy 索引 &切片 NumPy 索引 NumPy 切片 NumPy 高级索引 NumPy 高级索引 NumPy 字段访问 NumPy 使用布尔数组切片

数组属性与操作

NumPy 数组属性 NumPy 数组形状 NumPy 数组大小 NumPy 数组步长 NumPy 数组元素大小 NumPy 广播 NumPy 算术运算 NumPy 数组加法 NumPy 数组减法 NumPy 数组乘法 NumPy 数组除法

高级数组运算

NumPy 交换数组的轴 NumPy 字节交换 NumPy 副本和视图 NumPy 逐元素数组比较 NumPy 过滤数组 NumPy 连接数组 NumPy 排序、搜索& 计数函数 NumPy 搜索数组 NumPy 数组并集 NumPy 查找唯一行 NumPy 创建日期时间数组 NumPy 二元运算符 NumPy 字符串函数 NumPy 矩阵库 NumPy 线性代数 NumPy Matplotlib NumPy 使用 Matplotlib 绘制直方图

排序和高级操作

NumPy 数组排序 NumPy 沿轴排序 NumPy 使用花式索引进行排序 NumPy 结构化数组 NumPy 创建结构化数组 NumPy 操作结构化数组 NumPy 记录数组 NumPy 加载数组 NumPy 保存数组 NumPy 将值附加到数组 NumPy 交换列数组 NumPy 将轴插入数组

处理缺失数据

NumPy 处理缺失数据 NumPy 识别缺失值 NumPy 移除缺失数据 NumPy 插补缺失值数据

性能优化

NumPy 使用数组进行性能优化

线性代数

NumPy 线性代数 NumPy 矩阵库 NumPy 矩阵加法 NumPy 矩阵减法 NumPy 矩阵乘法 NumPy 逐元素矩阵运算 NumPy 点积 NumPy 矩阵求逆 NumPy 行列式计算 NumPy 特征值 NumPy 特征向量 NumPy 奇异值分解 NumPy 求解线性方程 NumPy 矩阵范数

元素级矩阵运算

NumPy 总和 NumPy 平均值 NumPy 中位数 NumPy 最小值 NumPy 最大值

集合运算

NumPy 唯一元素 NumPy 交集 NumPy 并集 NumPy 差集

随机数生成

NumPy 随机数生成器 NumPy 排列和重排 NumPy 均匀分布 NumPy 正态分布 NumPy 二项分布 NumPy 泊松分布 NumPy 指数分布 NumPy 瑞利分布 NumPy 逻辑分布 NumPy 帕累托分布 NumPy 使用 Seaborn 可视化分布 NumPy 多项分布 NumPy 卡方分布 NumPy Zipf 分布

文件输入 &输出

NumPy 使用 NumPy 进行 I/O NumPy 从文件读取数据 NumPy 将数据写入文件 NumPy 支持的文件格式

数学函数

NumPy 数学函数 NumPy 三角函数 NumPy 指数函数 NumPy 对数函数 NumPy 双曲函数 NumPy 舍入函数

傅里叶变换

NumPy 离散傅里叶变换 (DFT) NumPy 快速傅里叶变换 (FFT) NumPy 逆傅里叶变换 NumPy 傅里叶级数和变换 NumPy 信号处理应用 NumPy 卷积

多项式

NumPy 多项式表示 NumPy 多项式运算 NumPy 求多项式的根 NumPy 求多项式的根

统计

NumPy 统计函数 NumPy 描述性统计

日期时间函数

NumPy 日期和时间基础知识 NumPy 表示日期和时间 NumPy 日期和时间运算 NumPy 使用日期时间进行索引 NumPy 时区处理 NumPy 时间序列分析 NumPy 处理时间增量 NumPy 闰秒处理 NumPy 矢量化日期时间运算

ufunc

NumPy ufunc 简介 NumPy 创建通用函数 (ufunc) NumPy 算术通用函数 (ufunc) NumPy 小数舍入 ufunc NumPy 对数通用函数(ufunc) NumPy 求和通用函数 (ufunc) NumPy 乘积通用函数 (ufunc) NumPy 差分通用函数 (ufunc) NumPy 寻找最小公倍数 (LCM) NumPy 寻找最大公约数 (GCD) NumPy 三角函数 (ufunc) NumPy 双曲线 (ufunc) NumPy 集合运算(ufunc)

实用资源

NumPy 快速指南 NumPy 备忘单


NumPy - 数据类型

NumPy 数据类型

NumPy 支持的数值类型比 Python 多得多。下表列出了 NumPy 中定义的各种标量数据类型。

序号 数据类型 &说明
1

bool_

以字节形式存储的布尔值(True 或 False)

2

int_

默认整数类型(与 C 语言的 long 类型相同;通常为 int64 或 int32)

3

intc

与 C 语言的 int 类型相同(通常为 int32 或 int64)

4

intp

用于索引的整数(与 C 语言的 ssize_t 相同;通常为 int32 或 int64)

5

int8

字节 (-128 到 127)

6

int16

整数 (-32768 到 32767)

7

int32

整数 (-2147483648 至 2147483647)

8

int64

整数 (-9223372036854775808 至 9223372036854775807)

9

uint8

无符号整数(0 至 255)

10

uint16

无符号整数(0 至 65535)

11

uint32

无符号整数(0 至 4294967295)

12

uint64

无符号整数(0 至18446744073709551615)

13

float_

float64 的简写

14

float16

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

15

float32

单精度浮点数:符号位,指数 8 位,尾数 23 位尾数

16

float64

双精度浮点数:符号位,11 位指数,52 位尾数

17

complex_

complex128 的简写

18

complex64

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

19

complex128

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

NumPy 数值类型是 dtype(数据类型)对象的实例,每个对象都具有独特的特性。可用的数据类型包括 np.bool_、np.float32 等。

数据类型对象 (dtype)

数据类型对象描述对数组对应固定内存块的解释,具体取决于以下方面:

  • 数据类型(整数、浮点数或 Python 对象)

  • 数据大小

  • 字节顺序(小端或大端)

  • 如果是结构化类型,则字段名称、每个字段的数据类型以及每个字段占用的内存块部分。

  • 如果数据类型是子数组,则其形状和数据类型

字节顺序通过在数据类型前添加 '<' 或 '>' 前缀来决定。'<' 表示编码为小端序(最低有效位存储在最小地址中)。'>' 表示编码为大端序(最高有效位存储在最小地址中)。

使用以下语法构造 dtype 对象 -

numpy.dtype(object, align, copy)

参数如下 -

  • Object - 待转换为数据类型 object

  • Align - 如果为 true,则向字段添加填充,使其类似于 C 结构体

  • Copy - 复制 dtype 对象。如果为 false,则结果为对内置数据类型对象的引用

示例:使用数组标量类型

import numpy as np
dt = np.dtype(np.int32)
print(dt)

以下是获得的输出 -

int32

示例:使用等效字符串作为数据类型

import numpy as np
dt = np.dtype('i4')
print(dt)

这将产生以下结果 -

int32

示例:使用 Endian 表示法

import numpy as np
dt = np.dtype('>i4')
print(dt)

以下是上述代码的输出 -

>i4

示例:创建结构化数据类型

以下示例展示了结构化数据类型的用法。这里需要声明字段名称和对应的标量数据类型 -

import numpy as np
dt = np.dtype([('age', np.int8)])
print(dt)

输出结果如下 -

[('age', 'i1')]

示例:将结构化数据类型应用于 ndarray

import numpy as np
dt = np.dtype([('age', np.int8)])
a = np.array([(10,), (20,), (30,)], dtype=dt)
print(a)

执行上述代码后,我们得到以下输出 -

[(10,) (20,) (30,)]

示例:访问结构化数据类型的字段内容

import numpy as np
dt = np.dtype([('age', np.int8)])
a = np.array([(10,), (20,), (30,)], dtype=dt)
print(a['age'])

生成的结果如下 -

[10 20 30]

示例:定义复杂的结构化数据类型

以下示例定义了一个名为 student 的结构化数据类型,其中包含一个字符串字段"name",一个整数字段"age"和一个浮点型字段"marks"。此数据类型应用于 ndarray 对象 -

import numpy as np
student = np.dtype([('name', 'S20'), ('age', 'i1'), ('marks', 'f4')])
print(student)

我们得到如下所示的输出 -

[('name', 'S20'), ('age', 'i1'), ('marks', '<f4')])

示例:将复杂结构化数据类型应用于 ndarray

import numpy as np
student = np.dtype([('name', 'S20'), ('age', 'i1'), ('marks', 'f4')])
a = np.array([('abc', 21, 50), ('xyz', 18, 75)], dtype=student)
print(a)

输出如下 −

[('abc', 21, 50.0), ('xyz', 18, 75.0)]

每个内置数据类型都有一个唯一标识它的字符代码。

  • 'b' − 布尔值

  • 'i' − (有符号)整数

  • 'u' − 无符号整数

  • 'f' − 浮点数

  • 'c' − 复数浮点数

  • 'm' − 时间增量

  • 'M' − 日期时间

  • 'O' − (Python) 对象

  • 'S', 'a' − (字节)字符串

  • 'U' − Unicode

  • 'V' − 原始数据 (void)

检查数组的数据类型

您可以使用 dtype 属性检查数组的数据类型。此属性返回一个 dtype 对象,该对象描述数组中元素的类型,如下所示 -

import numpy as np
a = np.array([1, 2, 3])
print(a.dtype)

以下是获得的输出 -

int64

创建具有定义数据类型的数组

在 NumPy 中,您可以在创建数组时明确指定其元素的数据类型 (dtype)。

我们可以在数组创建函数(例如 np.array()、np.zeros()、np.ones() 等)中使用 dtype 参数来定义数组元素的数据类型。默认情况下,NumPy 会引用输入数据的数据类型。

示例:创建整数数组

在本例中,我们创建一个数组 a,其元素类型为 int32,这意味着每个元素都是一个 32 位整数 -

import numpy as np

# 创建指定数据类型的整数数组
a = np.array([1, 2, 3], dtype=np.int32)
print("数组:", a)
print("数据类型:", a.dtype)

这将产生以下结果 -

数组: [1 2 3]
数据类型: int32

示例:创建整数数组

这里,我们创建一个数组 c,其元素类型为 complex64,表示 64 位复数(32 位实部和 32 位虚部)。-

import numpy as np

# 创建指定 dtype 的复数数组
c = np.array([1+2j, 3+4j, 5+6j], dtype=np.complex64)
print("数组:", c)
print("数据类型:", c.dtype)

以下是上述代码的输出 -

数组:[1.+2.j 3.+4.j 5.+6.j]
数据类型:complex64

转换 NumPy 数组的数据类型

NumPy 提供了多种方法来转换数组的数据类型,允许您在不修改底层值的情况下更改数据的存储和处理方式 -

  • astype() 方法 - 这是最常用的类型转换方法。

  • numpy.cast() 函数 - NumPy 提供的一组函数,用于将数组转换为不同类型的类型。

  • 就地类型转换 - 在创建数组时直接转换类型。

示例:使用"astype"方法

astype 方法创建数组的副本,并将其转换为指定类型。这是更改数组数据类型最常用的方法。

这里,我们使用 NumPy 中的 astype() 方法将一个整数数组转换为浮点数据类型 -

import numpy as np

# 创建整数数组
a = np.array([1, 2, 3, 4, 5])
print("原始数组:", a)
print("原始数据类型:", a.dtype)

# 转换为浮点型
a_float = a.astype(np.float32)
print("转换后的数组:", a_float)
print("转换后的数据类型:", a_float.dtype)

得到的输出如下所示 -

原始数组:[1 2 3 4 5]
原始数据类型:int64
转换后的数组:[1. 2. 3. 4. 5.]
转换后的数据类型:float32

示例:使用"numpy.cast"函数

NumPy 还提供了将数组转换为特定类型的函数。这些函数不太常用,但在某些情况下很方便。

在本例中,我们创建一个浮点数数组,并使用 numpy.int32() 函数将其转换为整数 -

import numpy as np

# 创建一个浮点数数组
d = np.array([1.1, 2.2, 3.3, 4.4, 5.5])
print("原始数组:", d)
print("原始数据类型:", d.dtype)

# 使用 numpy.int32 转换为整数
d_int = np.int32(d)
print("转换后的数组:", d_int)
print("转换后的数据类型:", d_int.dtype)

执行上述代码后,我们得到以下输出 −

原始数组:[1.1 2.2 3.3 4.4 5.5]
原始数据类型:float64
转换后的数组:[1 2 3 4 5]
转换后的数据类型:int32

示例:就地类型转换

您还可以在创建数组时指定数据类型,以避免稍后进行类型转换。

现在,我们使用 numpy.float32() 函数指定浮点数据类型来创建一个整数数组 -

import numpy as np

# 创建指定数据类型的整数数组
e = np.array([1, 2, 3, 4, 5], dtype=np.float32)
print("数组:", e)
print("数据类型:", e.dtype)

生成的结果如下 -

数组:[1. 2. 3. 4. 5.]
数据类型:float32

如果值无法转换怎么办?

在 NumPy 中转换数据类型时,您可能会遇到无法转换为所需类型的值。这种情况通常会引发错误或导致意外行为。

让我们探讨一下无法转换值的不同场景以及如何处理它们 -

场景 1:将非数字字符串转换为数字

如果您尝试将非数字字符串转换为整数或浮点数,NumPy 将引发 ValueError,如下所示 -

import numpy as np

# 创建包含非数字字符串的数组
a = np.array(['1', '2', 'three', '4', '5'])
print("原始数组:", a)
print("原始数据类型:", a.dtype)

try:
    # 尝试转换为整数
    a_int = a.astype(np.int32)
    print("转换后的数组:", a_int)
    print("转换后的数据类型:", a_int.dtype)
except ValueError as e:
   print("Error:", e)

在本例中,字符串"three"无法转换为整数,导致 ValueError,如下图所示 -

原始数组:['1' '2' 'three' '4' '5']
原始数据类型:<U5
Error: invalid literal for int() with base 10: 'three'

场景 2:转换超出范围的数字

如果您尝试转换超出目标数据类型范围的数字,NumPy 将引发 OverflowError -

import numpy as np

# 创建一个包含较大浮点值的数组
b = np.array([1.1e10, 2.2e10, 3.3e10])
print("原始数组:", b)
print("原始数据类型:", b.dtype)

try:
    # 尝试转换为整数
    b_int = b.astype(np.int32)
    print("转换后的数组:", b_int)
    print("转换后的数据类型:", b_int.dtype)
except OverflowError as e:
   print("Error:", e)

此处,较大的浮点值无法转换为 int32 类型,否则会溢出 -

原始数组:[1.1e+10 2.2e+10 3.3e+10]
原始数据类型:float64
Error: OverflowError: (34, 'Numerical result out of range')

场景 3:将复数转换为实数

将复数转换为实数时,NumPy 会丢弃虚部并引发 ComplexWarning -

import numpy as np

# 创建包含复数的数组
c = np.array([1+2j, 3+4j, 5+6j])
print("原始数组:", c)
print("原始数据类型:", c.dtype)

# 转换为浮点数,丢弃虚部
c_float = c.astype(np.float32)
print("转换后的数组:", c_float)
print("转换后的数据类型:", c_float.dtype)

在本例中,NumPy引发 ComplexWarning 并在转换过程中丢弃虚部 -

原始数组:[1.+2.j 3.+4.j 5.+6.j]
原始数据类型:complex128
ComplexWarning: Casting complex values to real discards the imaginary partc_float = c.astype(np.float32)
转换后的数组:[1. 3. 5.]
转换后的数据类型:float32

场景 4:处理转换错误

要处理转换错误,您可以使用错误处理技术(例如 try-except 块)来捕获和处理异常。

import numpy as np

# 创建包含混合数据的数组
d = np.array(['1', '2', 'three', '4', '5'])
print("原始数组:", d)
print("原始数据类型:", d.dtype)

def safe_convert(arr, target_type):
   try:
      return arr.astype(target_type)
   except ValueError as e:
      print("Conversion error:", e)
      return None

# 尝试转换为整数
d_int = safe_convert(d, np.int32)
if d_int is not None:
    print("转换后的数组:", d_int)
    print("转换后的数据类型:", d_int.dtype)
else:
   print("Conversion failed.")

在此示例中,safe_convert() 函数捕获了"ValueError"并通过返回 None 并打印错误消息来处理它,如下图所示 -

原始数组:['1' '2' 'three' '4' '5']
原始数据类型:<U5
Conversion error: invalid literal for int() with base 10: 'three'
Conversion failed.

场景 5:使用"np.nan"进行无效转换

对于数值转换,可以使用 np.nan(非数字)来处理无效值。此方法在处理缺失或损坏的数据时非常有用。

import numpy as np

# 创建一个包含无效条目的字符串数组
e = np.array(['1.1', '2.2', 'three', '4.4', '5.5'])
print("原始数组:", e)
print("原始数据类型:", e.dtype)

def convert_with_nan(arr):
   result = []
   for item in arr:
      try:
         result.append(float(item))
      except ValueError:
         result.append(np.nan)
   return np.array(result)

# 使用 np.nan 将无效条目转换为浮点型
e_float = convert_with_nan(e)
print("转换后的数组:", e_float)
print("转换后的数据类型:", e_float.dtype)

此处,无效条目被替换为 np.nan -

原始数组:['1.1' '2.2' 'three' '4.4' '5.5']
原始数据类型:<U5
转换后的数组:[1.1 2.2 nan 4.4 5.5]
转换后的数据类型:float64

转换现有数组的数据类型

您还可以使用 view() 方法转换现有数组的数据类型,以更改数据的解释,而无需更改底层字节。

示例

此处,数据被重新解释为"float32",由于底层字节保持不变,因此导致出现意外值 -

import numpy as np

# 创建整数数组
g = np.array([1, 2, 3, 4], dtype=np.int32)
print("原始数组:", g)
print("原始数据类型:", g.dtype)

# 将数组视为 float32
g_view = g.view(np.float32)
print("查看后的数组:", g_view)
print("查看后的数据类型:", g_view.dtype)

以下是上述代码的输出 -

原始数组:[1 2 3 4]
原始数据类型:int32
查看后的数组:[1.4012985e-45 2.8025969e-45 4.2038954e-45 5.6051939e-45]
查看后的数据类型:float32