在 Python 数据科学和科学计算领域,NumPy 是一个核心且基础的库。它提供了强大的多维数组对象以及用于处理这些数组的各种工具,包括高效的数学运算、线性代数操作、随机数生成等功能。本文将全方位详细介绍 NumPy,从数组的创建、操作到高级应用,深入探讨索引和切片操作、广播机制等重要特性,还会对 NumPy 与其他可选计算方式进行比较,帮助读者深入理解并掌握这一重要工具。
NumPy(Numerical Python)是 Python 的一个开源数值计算扩展库,它是许多其他科学计算和数据分析库(如 Pandas、Scikit - learn 等)的基础。NumPy 的核心是 ndarray
(N - dimensional array,多维数组)对象,它能够高效地存储和处理大规模的多维数据。
如果你使用的是 Anaconda 环境,NumPy 通常已经预装。如果没有,可以使用 pip
进行安装:
pip install numpy
import numpy as np
# 创建一维数组
list1 = [1, 2, 3, 4, 5]
arr1 = np.array(list1)
print("一维数组:", arr1)
# 创建二维数组
list2 = [[1, 2, 3], [4, 5, 6]]
arr2 = np.array(list2)
print("二维数组:\n", arr2)
函数 | 描述 | 示例 |
---|---|---|
np.zeros(shape) |
创建指定形状的全零数组 | np.zeros((3, 4)) 创建一个 3 行 4 列的全零二维数组 |
np.ones(shape) |
创建指定形状的全一数组 | np.ones((2, 2)) 创建一个 2 行 2 列的全一二维数组 |
np.arange(start, stop, step) |
创建一个从 start 到 stop (不包含),步长为 step 的一维数组 |
np.arange(0, 10, 2) 创建 [0, 2, 4, 6, 8] |
np.linspace(start, stop, num) |
创建一个从 start 到 stop ,包含 num 个元素的一维数组 |
np.linspace(0, 1, 5) 创建 [0. , 0.25, 0.5 , 0.75, 1. ] |
np.random.rand(shape) |
创建指定形状的,元素在 [0, 1) 区间均匀分布的随机数组 |
np.random.rand(2, 3) 创建一个 2 行 3 列的随机二维数组 |
np.random.randn(shape) |
创建指定形状的,元素服从标准正态分布的随机数组 | np.random.randn(3) 创建一个长度为 3 的一维随机数组 |
zeros_arr = np.zeros((2, 3))
print("全零数组:\n", zeros_arr)
ones_arr = np.ones((2, 2))
print("全一数组:\n", ones_arr)
arange_arr = np.arange(0, 10, 2)
print("arange 创建的数组:", arange_arr)
linspace_arr = np.linspace(0, 1, 5)
print("linspace 创建的数组:", linspace_arr)
rand_arr = np.random.rand(2, 3)
print("随机均匀分布数组:\n", rand_arr)
randn_arr = np.random.randn(3)
print("随机正态分布数组:", randn_arr)
属性 | 描述 | 示例 |
---|---|---|
ndarray.shape |
返回数组的形状,是一个元组 | arr2.shape 对于 [[1, 2, 3], [4, 5, 6]] 返回 (2, 3) |
ndarray.ndim |
返回数组的维度 | arr2.ndim 返回 2 |
ndarray.size |
返回数组中元素的总数 | arr2.size 返回 6 |
ndarray.dtype |
返回数组元素的数据类型 | arr2.dtype 可能返回 int64 等 |
print("数组形状:", arr2.shape)
print("数组维度:", arr2.ndim)
print("数组元素总数:", arr2.size)
print("数组数据类型:", arr2.dtype)
一维数组的索引和切片操作与 Python 列表类似,但更加灵活高效。索引从 0 开始,负数索引表示从数组末尾开始计数。切片操作使用 [start:stop:step]
的形式,start
表示起始位置,stop
表示结束位置(不包含),step
表示步长。
arr1 = np.array([1, 2, 3, 4, 5])
print("第一个元素:", arr1[0]) # 访问第一个元素
print("最后一个元素:", arr1[-1]) # 访问最后一个元素
print("前三个元素:", arr1[:3]) # 切片操作,获取前三个元素
print("后两个元素:", arr1[-2:]) # 获取后两个元素
print("间隔为 2 的元素:", arr1[::2]) # 步长为 2,获取间隔元素
多维数组的索引和切片需要为每个维度指定索引或切片范围。可以使用逗号分隔不同维度的索引或切片。
arr2 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print("第一行第二列元素:", arr2[0, 1]) # 访问第一行第二列的元素
print("第一行所有元素:", arr2[0, :]) # 获取第一行的所有元素
print("第二列所有元素:", arr2[:, 1]) # 获取第二列的所有元素
print("前两行的前两列元素:\n", arr2[:2, :2]) # 获取前两行的前两列元素
NumPy 数组支持基本的算术运算,如加法、减法、乘法、除法等。这些运算会对数组中的每个元素进行操作。
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
print("加法:", arr1 + arr2)
print("减法:", arr1 - arr2)
print("乘法:", arr1 * arr2)
print("除法:", arr1 / arr2)
NumPy 提供了矩阵运算的功能,如矩阵乘法。可以使用 np.dot()
函数或 @
运算符进行矩阵乘法。
arr1 = np.array([[1, 2], [3, 4]])
arr2 = np.array([[5, 6], [7, 8]])
# 矩阵乘法
mat_mul = np.dot(arr1, arr2)
print("矩阵乘法结果:\n", mat_mul)
# 也可以使用 @ 运算符
mat_mul_alt = arr1 @ arr2
print("使用 @ 运算符的矩阵乘法结果:\n", mat_mul_alt)
广播机制是 NumPy 中一种强大的特性,它允许在不同形状的数组之间进行算术运算。当两个数组的形状不完全相同时,NumPy 会自动将它们扩展为相同的形状,以便进行元素级的运算。
ValueError
异常。# 示例 1:一维数组与标量相加
arr = np.array([1, 2, 3])
scalar = 2
result = arr + scalar
print("一维数组与标量相加结果:", result)
# 示例 2:二维数组与一维数组相加
arr2d = np.array([[1, 2, 3], [4, 5, 6]])
arr1d = np.array([1, 2, 3])
result = arr2d + arr1d
print("二维数组与一维数组相加结果:\n", result)
可以使用 reshape()
方法改变数组的形状,但要确保新形状的元素总数与原数组相同。
arr = np.arange(12)
reshaped_arr = arr.reshape(3, 4)
print("重塑后的数组:\n", reshaped_arr)
可以使用 np.vstack()
(垂直拼接)和 np.hstack()
(水平拼接)函数将多个数组拼接在一起。
arr1 = np.array([[1, 2], [3, 4]])
arr2 = np.array([[5, 6], [7, 8]])
# 垂直拼接
vertical_stack = np.vstack((arr1, arr2))
# 水平拼接
horizontal_stack = np.hstack((arr1, arr2))
print("垂直拼接结果:\n", vertical_stack)
print("水平拼接结果:\n", horizontal_stack)
可以使用 np.vsplit()
(垂直分割)和 np.hsplit()
(水平分割)函数将数组分割成多个子数组。
arr = np.arange(12).reshape(3, 4)
# 垂直分割
vertical_split = np.vsplit(arr, 3)
# 水平分割
horizontal_split = np.hsplit(arr, 2)
print("垂直分割结果:", vertical_split)
print("水平分割结果:", horizontal_split)
NumPy 提供了许多统计函数,如计算均值、标准差、最大值、最小值等。
arr = np.array([1, 2, 3, 4, 5])
print("数组的均值:", np.mean(arr))
print("数组的标准差:", np.std(arr))
print("数组的最大值:", np.max(arr))
print("数组的最小值:", np.min(arr))
比较项 | Python 原生列表 | NumPy 数组 |
---|---|---|
存储效率 | 存储任意类型元素,需要额外的元数据,存储效率低 | 存储单一类型元素,存储紧凑,效率高 |
运算速度 | 元素级运算需要使用循环,速度慢 | 支持向量化运算,速度快 |
功能扩展性 | 基本的列表操作,功能有限 | 提供丰富的数学运算、线性代数等功能 |
比较项 | Pandas | NumPy |
---|---|---|
数据结构 | 提供 Series 和 DataFrame 等数据结构,适合处理表格数据和标签数据 |
主要使用 ndarray 处理多维数值数据 |
数据处理能力 | 强大的数据清洗、转换、分析功能,支持标签索引 | 侧重于数值计算和数组操作 |
性能 | 对于大规模数值计算,性能相对较低 | 高效的数值计算性能 |
比较项 | SciPy | NumPy |
---|---|---|
功能范围 | 提供更多高级科学计算功能,如优化、积分、信号处理等 | 基础的数值计算和数组操作 |
依赖关系 | 基于 NumPy 构建,依赖 NumPy 的数组对象 | 是独立的基础库 |
Pandas 是基于 NumPy 构建的数据分析库,它使用 NumPy 的 ndarray
作为底层数据结构。Pandas 的 Series
和 DataFrame
对象在处理表格数据时非常方便,而 NumPy 则为其提供了高效的数值计算基础。
Matplotlib 是 Python 的绘图库,它可以与 NumPy 紧密结合。NumPy 数组可以作为 Matplotlib 绘图函数的输入,用于绘制各种图表,如折线图、柱状图、散点图等。
import matplotlib.pyplot as plt
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.plot(x, y)
plt.show()
NumPy 是 Python 科学计算领域的基石,它提供了高效的多维数组对象和丰富的数组操作功能。通过本文的介绍,我们学习了 NumPy 数组的创建、基本操作、高级操作,深入了解了索引和切片操作、广播机制等重要特性,还对 NumPy 与其他可选计算方式进行了比较。掌握 NumPy 对于从事数据科学、机器学习、深度学习等领域的开发者来说是必不可少的。