Skip to content

NumPy 线性代数

本章目标

  1. 掌握向量点积与矩阵乘法(dot / matmul / @)的区别与使用场景
  2. 掌握转置、行列式、逆矩阵的基本用法
  3. 会求方阵的特征值与特征向量
  4. 会用 np.linalg.solve 解线性方程组 Ax=b
  5. 掌握 np.linalg.norm 计算常见向量与矩阵范数

重点方法与概念速览

名称类型作用
np.dot(...)函数点积 / 矩阵乘法(兼容多维)
np.matmul(...) / @函数 / 运算符矩阵乘法(高维批量)
arr.T属性转置视图(反转所有维度)
np.transpose(...)函数转置,可指定轴顺序
np.linalg.det(...)函数方阵行列式
np.linalg.inv(...)函数方阵逆矩阵
np.linalg.eig(...)函数特征值与特征向量
np.linalg.solve(...)函数解线性方程组 Ax=b
np.linalg.norm(...)函数向量 / 矩阵范数
np.allclose(...)函数浮点容差比较

1. 点积与矩阵乘法

np.dot

作用

向量点积或矩阵乘法,行为随输入维度变化:

  • 两个一维向量 → 点积 ab=aibi,返回标量
  • 两个二维矩阵 → 矩阵乘法 Cik=jAijBjk
  • 高维数组 → 沿最后两轴做矩阵乘法

重点方法

python
np.dot(a, b, out=None)

参数

参数名类型说明示例取值
aarray_like第一个输入[1, 2, 3]A(2x2)
barray_like第二个输入,形状需与 a 在相应轴上匹配[4, 5, 6]B(2x2)
outndarrayNone写入结果的目标数组——

np.matmul / @

作用

专用的矩阵乘法,@ 是运算符写法。与 dot 的差异:

  • 不支持标量乘法
  • 高维时视为"批量矩阵乘法":最后两轴是矩阵维度,前轴做广播

重点方法

python
np.matmul(x1, x2, /, out=None, *, casting='same_kind', order='K', dtype=None)
# 等价运算符
A @ B

参数

参数名类型说明示例取值
x1array_like左矩阵A(2x2)
x2array_like右矩阵,列数需与 x1 行数匹配B(2x2)
outndarrayNone目标数组——
castingstr类型转换策略,默认为 'same_kind''safe'
dtypedtypeNone结果类型——

综合示例

示例代码

python
import numpy as np

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print(f"向量点积 np.dot(a, b) = {np.dot(a, b)}")

A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
print(f"A @ B:\n{A @ B}")
print(f"np.dot(A, B):\n{np.dot(A, B)}")

输出

text
向量点积 np.dot(a, b) = 32
A @ B:
[[19 22]
 [43 50]]
np.dot(A, B):
[[19 22]
 [43 50]]

理解重点

  • 现代代码优先用 @(可读性高、仅限矩阵乘法)
  • 需要向量点积或对标量操作时用 np.dot
  • 三维以上批量矩阵乘用 matmul / @,不要用 dot

2. 转置

arr.T

作用

返回数组的转置视图,所有维度顺序反转。对二维数组即常规"行列交换"。

返回内容

类型含义
ndarray转置视图,修改会影响原数组

np.transpose

作用

arr.T 更灵活,可通过 axes 参数指定任意的轴排列顺序。

重点方法

python
np.transpose(a, axes=None)

参数

参数名类型说明示例取值
aarray_like输入数组A(2x3)
axestuple[int, ...]None新轴顺序,默认为 None(反转所有维度)(1, 0)(1, 0, 2)

示例代码

python
import numpy as np

A = np.array([[1, 2, 3], [4, 5, 6]])
print(f"A (2x3):\n{A}")
print(f"A.T (3x2):\n{A.T}")
print(f"np.transpose(A):\n{np.transpose(A)}")

输出

text
A (2x3):
[[1 2 3]
 [4 5 6]]
A.T (3x2):
[[1 4]
 [2 5]
 [3 6]]
np.transpose(A):
[[1 4]
 [2 5]
 [3 6]]

3. 行列式与逆矩阵

np.linalg.det

作用

计算方阵的行列式。行列式为 0 表示矩阵奇异(不可逆)。公式(以 2×2 为例):

det(abcd)=adbc

重点方法

python
np.linalg.det(a)

参数

参数名类型说明示例取值
aarray_like方阵,至少二维;高维时对最后两轴批量计算[[4, 7], [2, 6]]

np.linalg.inv

作用

计算方阵的逆矩阵 A1,满足 AA1=I。对奇异或接近奇异的矩阵数值不稳定,应改用 solve

重点方法

python
np.linalg.inv(a)

参数

参数名类型说明示例取值
aarray_like方阵;行列式为 0 时抛 LinAlgError[[4, 7], [2, 6]]

np.allclose

作用

判断两个数组在给定容差内是否近似相等。浮点数不应直接 == 比较,应用 allclose。判断条件:

|ab|atol+rtol|b|

重点方法

python
np.allclose(a, b, rtol=1e-05, atol=1e-08, equal_nan=False)

参数

参数名类型说明示例取值
aarray_like待比较的数组 1A @ A_inv
barray_like待比较的数组 2np.eye(2)
rtolfloat相对容差,默认为 1e-051e-10
atolfloat绝对容差,默认为 1e-081e-12
equal_nanboolTrue 时将两个 NaN 视为相等,默认为 FalseTrue

综合示例

示例代码

python
import numpy as np

A = np.array([[4, 7], [2, 6]])
det = np.linalg.det(A)
AInv = np.linalg.inv(A)

print(f"det(A) = {det:.4f}")
print(f"A^-1:\n{AInv}")
print(f"A @ A^-1:\n{(A @ AInv).round(10)}")
print(f"是否单位矩阵: {np.allclose(A @ AInv, np.eye(2))}")

输出

text
det(A) = 10.0000
A^-1:
[[ 0.6 -0.7]
 [-0.2  0.4]]
A @ A^-1:
[[ 1.  0.]
 [-0.  1.]]
是否单位矩阵: True

4. 特征值与特征向量

np.linalg.eig

作用

计算方阵 A 的特征值与特征向量,满足:

Av=λv

返回二元组 (eigenvalues, eigenvectors)

重点方法

python
np.linalg.eig(a)

参数

参数名类型说明示例取值
aarray_like输入方阵[[4, 2], [1, 3]]

返回值

返回值类型含义
eigenvaluesndarray一维数组,长度等于方阵阶数
eigenvectorsndarray二维数组,ieigenvalues[i] 对应的特征向量

示例代码

python
import numpy as np

A = np.array([[4, 2], [1, 3]])
eigenvalues, eigenvectors = np.linalg.eig(A)

print(f"特征值: {eigenvalues}")
print(f"特征向量:\n{eigenvectors}")

# 验证 A @ v = λ @ v
for i in range(len(eigenvalues)):
    v = eigenvectors[:, i]
    lam = eigenvalues[i]
    print(f"λ={lam:.2f}: A@v = {A @ v}, λ*v = {lam * v}, "
          f"相等={np.allclose(A @ v, lam * v)}")

输出

text
特征值: [5. 2.]
特征向量:
[[ 0.89442719 -0.70710678]
 [ 0.4472136   0.70710678]]
λ=5.00: A@v = [4.47213595 2.23606798], λ*v = [4.47213595 2.23606798], 相等=True
λ=2.00: A@v = [-1.41421356  1.41421356], λ*v = [-1.41421356  1.41421356], 相等=True

理解重点

  • 特征向量按存放,切片用 eigvecs[:, i],不是 eigvecs[i]
  • 特征值可能为复数(即使输入全为实数),返回类型可能为 complex128
  • 对称矩阵用 np.linalg.eigh 得到更稳定的实值结果

5. 解线性方程组

np.linalg.solve

作用

解线性方程组 Ax=b。比 inv(A)@b 更快更稳定,应始终作为首选。本质是通过 LU 分解等数值方法直接求解,避免显式计算逆矩阵。

重点方法

python
np.linalg.solve(a, b)

参数

参数名类型说明示例取值
aarray_like系数方阵,必须可逆[[2, 1], [1, 3]]
barray_like右端向量(或多个右端组成的矩阵)[5, 7]

示例代码

python
import numpy as np

# 方程组:
#   2x + y = 5
#   x + 3y = 7
A = np.array([[2, 1], [1, 3]])
b = np.array([5, 7])

x = np.linalg.solve(A, b)
print(f"解 x = {x}")
print(f"验证 A @ x = {A @ x}")
print(f"是否等于 b: {np.allclose(A @ x, b)}")

输出

text
解 x = [1.6 1.8]
验证 A @ x = [5. 7.]
是否等于 b: True

理解重点

  • 永远优先 solve,而不是 inv(A) @ b——前者更快且数值更稳定
  • 非方阵或超定 / 欠定系统用最小二乘 np.linalg.lstsq

6. 范数

np.linalg.norm

作用

计算向量或矩阵的范数。通过 ord 参数选择不同范数类型。

  • 向量 L2 范数(欧几里得距离):v2=|vi|2
  • 向量 L1 范数(曼哈顿距离):v1=|vi|
  • 矩阵 Frobenius 范数:AF=i,j|aij|2

重点方法

python
np.linalg.norm(x, ord=None, axis=None, keepdims=False)

参数

参数名类型说明示例取值
xarray_like向量或矩阵输入[3, 4]A(2x2)
ordintstrNone范数阶数,默认为 None(见下表)12np.inf
axisintNone指定按轴计算范数,默认为 None(整体计算)0
keepdimsbool是否保留被聚合的轴,默认为 FalseTrue

ord 常见取值

ord向量含义矩阵含义(二维输入)
None(默认)L2 范数 xi2Frobenius 范数
1L1 范数 |xi|列绝对值和的最大值
2L2 范数(同 None最大奇异值(谱范数)
np.inf最大绝对值 max|xi|行绝对值和的最大值
-np.inf最小绝对值 min|xi|行绝对值和的最小值
'fro'Frobenius 范数

示例代码

python
import numpy as np

v = np.array([3, 4])
print(f"L1 范数 (曼哈顿距离): {np.linalg.norm(v, ord=1)}")
print(f"L2 范数 (欧几里得距离): {np.linalg.norm(v, ord=2)}")
print(f"无穷范数: {np.linalg.norm(v, ord=np.inf)}")

A = np.array([[1, 2], [3, 4]])
print(f"Frobenius 范数: {np.linalg.norm(A):.4f}")

输出

text
L1 范数 (曼哈顿距离): 7.0
L2 范数 (欧几里得距离): 5.0
无穷范数: 4.0
Frobenius 范数: 5.4772

理解重点

  • 向量 [3,4] 的 L2 范数为 32+42=5
  • 矩阵默认范数是 Frobenius,等于把矩阵展平为向量后的 L2 范数

常见坑

  1. 只有方阵才能直接 inv / det / eig——非方阵考虑 SVD 或伪逆 np.linalg.pinv
  2. 奇异或接近奇异的矩阵求逆数值不稳定,条件数大时结果误差大
  3. 解线性方程组永远np.linalg.solve,不要写 np.linalg.inv(A) @ b
  4. 比较浮点结果用 np.allclose,不要直接用 ==
  5. @np.dot 在高维数组上的广播语义不同:批量矩阵乘用 @ / matmul
  6. np.linalg.eig 的特征向量按存放,切片写成 eigvecs[i] 是错误

小结

  • 本章是机器学习线代工具箱的基础:solveeignorm 出现频率最高
  • 理解维度匹配规则(m×k @ k×nm×n)是避免维度错误的关键
  • 浮点比较用 allclose,求逆用 solve——这两点能避开 90% 的初学者陷阱