AI_Python基础-9.NumPy
·
NumPy 数值计算基础
标签: #Python #NumPy #数值计算 #ndarray #广播机制 #线性代数
学习周期:2 天 | 核心目标:掌握 NumPy 多维数组的创建、索引、运算及广播机制,为数据分析和机器学习打下基础
4.1 NumPy(数值计算)
NumPy(Numerical Python)是 Python 科学计算的核心库,提供了高性能的多维数组对象 ndarray 和丰富的数组运算函数。几乎所有数据分析和机器学习库(如 Pandas、Scikit-learn、TensorFlow)都基于 NumPy。
核心优势:高速度(底层 C 语言实现)、高内存效率、丰富的数值运算功能。
安装与导入
pip install numpy
import numpy as np
4.1.1 ndarray 多维数组的创建与属性(shape, dtype)
1. 创建数组
从列表/元组创建
# 一维数组
arr1 = np.array([1, 2, 3, 4, 5])
# 二维数组(列表嵌套)
arr2 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 指定数据类型
arr_float = np.array([1, 2, 3], dtype=np.float64)
arr_int = np.array([1, 2, 3], dtype=np.int32)
内置创建函数(常用)
| 函数 | 说明 | 示例 |
|---|---|---|
np.zeros(shape) |
全0数组 | np.zeros((2,3)) |
np.ones(shape) |
全1数组 | np.ones((3,2), dtype=np.int32) |
np.eye(N) |
单位矩阵(N×N) | np.eye(3) |
np.full(shape, value) |
填充指定值 | np.full((2,3), 7) |
np.arange(start, stop, step) |
等差数列(类似 range) | np.arange(0, 10, 2) → [0,2,4,6,8] |
np.linspace(start, stop, num) |
等间隔序列 | np.linspace(0, 1, 5) → [0.,0.25,0.5,0.75,1.] |
np.random.rand(d0,d1) |
[0,1) 均匀分布 | np.random.rand(2,3) |
np.random.randn(d0,d1) |
标准正态分布 | np.random.randn(2,3) |
np.random.randint(low, high, size) |
随机整数 | np.random.randint(0, 10, (2,3)) |
2. 数组属性
arr = np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float64)
print(arr.shape) # (2, 3) → 2行3列
print(arr.ndim) # 2 → 维度数
print(arr.size) # 6 → 元素总数
print(arr.dtype) # float64 → 数据类型
print(arr.itemsize) # 8 → 每个元素字节数
# 改变形状(不改变原数组,返回新数组)
arr_reshape = arr.reshape((3, 2))
易错点:
np.array()中的元素类型必须一致,否则会自动向上转换(如 int + float → float)。reshape()新形状的元素总数必须与原数组相同。- 一维数组的
shape是(n,),注意末尾逗号。
4.1.2 索引、切片、布尔索引、花式索引
基础索引(按位置)
arr1 = np.arange(10)
print(arr1[3]) # 3
print(arr1[-1]) # 9
arr2 = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(arr2[0,0]) # 1
print(arr2[1,2]) # 6
print(arr2[2]) # [7,8,9](整行)
切片(范围取值)
# 一维切片
arr1 = np.arange(10)
print(arr1[2:5]) # [2,3,4]
print(arr1[::2]) # [0,2,4,6,8]
# 二维切片
arr2 = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(arr2[:2, :2]) # [[1,2],[4,5]]
print(arr2[:, 1]) # [2,5,8](第2列)
print(arr2[1, :]) # [4,5,6](第2行)
# ⚠️ 切片返回视图,修改会影响原数组
slice_view = arr2[:2, :2]
slice_view[0,0] = 100
print(arr2[0,0]) # 变为100
布尔索引(条件筛选)
arr = np.array([[1,2,3],[4,5,6],[7,8,9]])
mask = arr > 5
print(mask) # 布尔数组
print(arr[mask]) # [6,7,8,9]
# 多条件(& 且,| 或,注意括号)
print(arr[(arr > 3) & (arr < 8)]) # [4,5,6,7]
print(arr[(arr == 2) | (arr == 8)]) # [2,8]
花式索引(整数列表索引)
arr1 = np.arange(10)
indices = [1,3,5,7]
print(arr1[indices]) # [1,3,5,7]
arr2 = np.array([[1,2,3],[4,5,6],[7,8,9]])
row = [0,2]; col = [1,2]
print(arr2[row, col]) # [2,9](取(0,1)和(2,2))
print(arr2[[0,2], :]) # 取第1行和第3行的所有列
索引方式对比
| 方式 | 返回类型 | 是否影响原数组 |
|---|---|---|
| 基础索引 | 标量或子数组 | 修改影响原数组 |
| 切片 | 视图(view) | 修改影响原数组 |
| 布尔索引 | 副本(copy) | 修改不影响原数组 |
| 花式索引 | 副本(copy) | 修改不影响原数组 |
4.1.3 广播机制(Broadcasting)
广播允许不同形状的数组进行算术运算,无需手动调整形状。
核心规则(从尾部维度对齐):
- 维度较少的数组在前面补1。
- 每个维度上,两个数组的形状要么相等,要么其中一个为1,要么缺失。
- 满足条件则可广播;否则报错
ValueError。
# 标量与数组
arr = np.array([1,2,3])
print(arr + 10) # [11,12,13]
# 一维 + 二维
a = np.array([[1,2,3],[4,5,6]]) # (2,3)
b = np.array([10,20,30]) # (3,) → 广播为 (1,3) → (2,3)
print(a + b) # 每行加 b
# 列向量广播
col = np.array([[1],[2],[3]]) # (3,1)
row = np.array([10,20,30]) # (3,) → (1,3)
print(col + row) # (3,3)
# 不兼容示例
# a = np.ones((3,2)); b = np.ones((4,)) → ValueError
4.1.4 通用函数(ufunc)
通用函数对数组逐元素高效运算,底层 C 实现,速度极快。
数学函数
arr = np.array([1,4,9,16])
print(np.sqrt(arr)) # [1.,2.,3.,4.]
print(np.exp(arr)) # e^x
print(np.log(arr)) # 自然对数
print(np.log10(arr)) # 以10为底
print(np.sin(arr)) # 正弦(弧度)
print(np.cos(arr))
print(np.abs([-1,-2])) # [1,2]
print(np.ceil(3.2)) # 4.0
print(np.floor(3.9)) # 3.0
二元通用函数
a = np.array([1,2,3])
b = np.array([4,5,6])
print(np.add(a,b)) # [5,7,9]
print(np.maximum(a,b)) # [4,5,6]
print(np.minimum(a,b)) # [1,2,3]
print(np.power(a,2)) # [1,4,9]
比较函数
print(np.greater(a,b)) # [False,False,False]
print(np.equal(a,b)) # [False,False,False]
4.1.5 数组运算
元素级算术运算
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
print(a + b) # 加法
print(a - b) # 减法
print(a * b) # 逐元素乘法(不是矩阵乘法)
print(a / b) # 除法
print(a ** 2) # 逐元素平方
矩阵乘法
# 方式1:@ 运算符(推荐)
print(a @ b)
# 方式2:np.dot()
print(np.dot(a, b))
# 方式3:np.matmul()
print(np.matmul(a, b))
# 一维数组点积
x = np.array([1,2,3])
y = np.array([4,5,6])
print(np.dot(x, y)) # 1*4+2*5+3*6=32
统计方法
arr = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(arr.sum()) # 45(总和)
print(arr.sum(axis=0)) # [12,15,18](按列求和)
print(arr.sum(axis=1)) # [6,15,24](按行求和)
print(arr.mean()) # 5.0
print(arr.mean(axis=0)) # [4.,5.,6.]
print(arr.std()) # 标准差
print(arr.var()) # 方差
print(arr.max()) # 9
print(arr.min()) # 1
print(arr.argmax(axis=0)) # 每列最大值的行索引 [2,2,2]
print(np.median(arr)) # 5.0(中位数)
print(arr.cumsum()) # 累积和 [1,3,6,10,15,21,28,36,45]
axis 参数理解:
axis=0:沿着行方向(垂直),对每一列操作axis=1:沿着列方向(水平),对每一行操作
4.1.6 线性代数基础(np.linalg)
import numpy as np
from numpy import linalg as LA
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
# 矩阵乘法
C = A @ B
# 转置
print(A.T) # [[1,3],[2,4]]
# 逆矩阵(仅方阵)
A_inv = LA.inv(A)
print(A @ A_inv) # 近似单位矩阵
# 行列式
det = LA.det(A) # -2.0
# 迹(对角线之和)
trace = np.trace(A) # 5
# 特征值和特征向量
eigenvalues, eigenvectors = LA.eig(A)
# 解线性方程组 Ax = b
A_eq = np.array([[3,1],[1,2]])
b_eq = np.array([9,8])
x = LA.solve(A_eq, b_eq) # [2.,3.]
# 矩阵的秩
rank = LA.matrix_rank(A) # 2
# 最小二乘法(拟合)
# x_lsq, residuals, rank, s = LA.lstsq(A, b, rcond=None)
注意事项:
- 求逆和行列式仅适用于方阵,非方阵会报错。
- 若矩阵奇异(行列式为0),
inv()会抛出LinAlgError。 solve()要求系数矩阵满秩,否则用lstsq()。
📚 学习资料(Obsidian 可直接收藏)
🎯 学习建议(2 天计划)
- 第 1 天:掌握
ndarray创建、属性、基本索引和切片,重点练习布尔索引和花式索引,理解广播机制。 - 第 2 天:学习通用函数、数组运算(矩阵乘法、统计方法),了解
np.linalg常用线性代数函数。
✅ 核心要点总结
ndarray:同质多维数组,核心属性shape、dtype、ndim、size。- 创建方式:
np.array()、np.zeros()、np.ones()、np.arange()、np.linspace()、np.random.rand()等。 - 索引与切片:基本索引、切片(返回视图)、布尔索引(返回副本)、花式索引(返回副本)。
- 广播机制:形状兼容的数组可直接运算,自动扩展维度,规则清晰。
- 通用函数(ufunc):
np.sqrt()、np.exp()、np.sin()等,逐元素高效计算。 - 数组运算:元素级算术运算;矩阵乘法用
@或np.dot();统计方法可指定axis。 - 线性代数:
np.linalg提供逆、行列式、特征值、解方程组等。
练习题(自测)
- 创建一个 5×5 的随机整数矩阵(范围 0-100),计算其均值、标准差、最大值和最小值。
- 创建两个 3×3 矩阵
A和B,计算A + B、A - B、A @ B以及A的转置。 - 使用布尔索引将数组中所有大于 5 的元素替换为 0。
- 创建一个形状为 (4, 3) 的数组,通过广播将每一行都减去该行的平均值(实现行中心化)。
- 解线性方程组:
2x + y = 5 x - 3y = -1 - 生成 1000 个服从正态分布的随机数,计算其均值和标准差,并绘制直方图(可使用 Matplotlib,选做)。
建议在 Jupyter Notebook 中逐步练习,观察数组形状和广播行为。
更多推荐
所有评论(0)