NumPy 线性代数

NumPy 提供了强大的线性代数功能,主要通过其子模块 numpy.linalg 实现。这些功能支持矩阵运算、向量运算、特征值分解、线性方程组求解等线性代数操作,广泛应用于科学计算、机器学习和工程领域。以下是对 NumPy 线性代数功能的详细中文讲解,涵盖核心功能、常见操作和示例。


1. 概述

numpy.linalg 模块提供了丰富的线性代数工具,用于处理矩阵和向量的运算。以下是主要功能的分类:

  • 矩阵运算:矩阵乘法、转置、逆矩阵、行列式等。
  • 线性方程组求解:求解 Ax = b 形式的方程。
  • 特征值与特征向量:计算矩阵的特征值和特征向量。
  • 矩阵分解:如 SVD(奇异值分解)、QR 分解等。
  • 范数与距离:计算矩阵或向量的范数。

要使用线性代数功能,需先导入 NumPy 和 linalg 模块:

import numpy as np
import numpy.linalg as la

2. 基本矩阵运算

以下是常见的矩阵操作及其实现方法。

2.1 矩阵乘法

矩阵乘法可以通过 np.dot()@ 运算符实现(numpy.matrix 类的 * 也支持矩阵乘法,但建议使用 ndarray)。

A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])

# 使用 @ 运算符
result = A @ B
print(result)
# 输出:
# [[19 22]
#  [43 50]]

# 使用 np.dot
result_dot = np.dot(A, B)
print(result_dot)
# 输出同上

2.2 矩阵转置

使用 np.transpose().T 属性计算矩阵转置。

A = np.array([[1, 2], [3, 4]])
print(A.T)
# 输出:
# [[1 3]
#  [2 4]]

2.3 矩阵的逆

使用 la.inv() 计算方阵的逆(矩阵必须是非奇异的,即行列式不为 0)。

A = np.array([[1, 2], [3, 4]])
A_inv = la.inv(A)
print(A_inv)
# 输出:
# [[-2.   1. ]
#  [ 1.5 -0.5]]

# 验证:A @ A_inv 应为单位矩阵
print(A @ A_inv)
# 输出:
# [[1. 0.]
#  [0. 1.]]

2.4 矩阵的行列式

使用 la.det() 计算矩阵的行列式。

A = np.array([[1, 2], [3, 4]])
det = la.det(A)
print(det)  # 输出: -2.0

2.5 矩阵的迹

矩阵的迹是主对角线元素之和,可用 np.trace() 计算。

A = np.array([[1, 2], [3, 4]])
trace = np.trace(A)
print(trace)  # 输出: 5 (1 + 4)

3. 线性方程组求解

求解线性方程组 Ax = b,其中 A 是系数矩阵,x 是未知向量,b 是常数向量。使用 la.solve() 求解。

示例

求解以下方程组:

2x + y = 5
x + 3y = 10

代码:

A = np.array([[2, 1], [1, 3]])
b = np.array([5, 10])
x = la.solve(A, b)
print(x)  # 输出: [1. 3.] (即 x = 1, y = 3)

注意

  • la.solve() 适用于方阵(A 必须是 n×n 矩阵)。
  • 如果 A 不可逆(奇异矩阵),会抛出 LinAlgError

4. 特征值与特征向量

使用 la.eig() 计算方阵的特征值和特征向量。

示例

A = np.array([[1, 2], [2, 1]])
eigenvalues, eigenvectors = la.eig(A)
print("特征值:", eigenvalues)
print("特征向量:\n", eigenvectors)
# 输出:
# 特征值: [ 3. -1.]
# 特征向量:
# [[ 0.70710678 -0.70710678]
#  [ 0.70710678  0.70710678]]

解释

  • eigenvalues 是一个一维数组,包含矩阵的特征值。
  • eigenvectors 是一个矩阵,每列是对应特征值的特征向量。

5. 矩阵分解

numpy.linalg 支持多种矩阵分解方法,常用的包括:

5.1 奇异值分解 (SVD)

SVD 将矩阵 A 分解为 U @ np.diag(s) @ Vh,其中 UVh 是正交矩阵,s 是奇异值向量。

A = np.array([[1, 2], [3, 4]])
U, s, Vh = la.svd(A)
print("U:\n", U)
print("奇异值:", s)
print("Vh:\n", Vh)
# 输出示例:
# U:
# [[-0.40455358 -0.9145143 ]
#  [-0.9145143   0.40455358]]
# 奇异值: [5.4649857  0.36596619]
# Vh:
# [[-0.57604844 -0.81741556]
#  [-0.81741556  0.57604844]]

5.2 QR 分解

QR 分解将矩阵分解为正交矩阵 Q 和上三角矩阵 R

A = np.array([[1, 2], [3, 4]])
Q, R = la.qr(A)
print("Q:\n", Q)
print("R:\n", R)
# 输出示例:
# Q:
# [[-0.31622777 -0.9486833 ]
#  [-0.9486833   0.31622777]]
# R:
# [[-3.16227766 -4.42718872]
#  [ 0.         -0.63245553]]

6. 范数与距离

6.1 矩阵或向量的范数

使用 la.norm() 计算范数(默认是 L2 范数)。

v = np.array([3, 4])
norm = la.norm(v)
print(norm)  # 输出: 5.0 (sqrt(3^2 + 4^2))

# 矩阵范数
A = np.array([[1, 2], [3, 4]])
norm_A = la.norm(A)  # 默认 Frobenius 范数
print(norm_A)  # 输出: 5.477225575051661

6.2 其他范数

支持的范数类型包括:

  • ord='fro':Frobenius 范数(矩阵默认)。
  • ord=2:L2 范数(向量默认)。
  • ord=1:L1 范数。
  • ord=np.inf:无穷范数。

7. 其他实用功能

7.1 矩阵的条件数

条件数衡量矩阵的数值稳定性,使用 la.cond() 计算。

A = np.array([[1, 2], [3, 4]])
cond = la.cond(A)
print(cond)  # 输出: 14.933034373659268

7.2 矩阵的秩

使用 la.matrix_rank() 计算矩阵的秩。

A = np.array([[1, 2], [2, 4]])
rank = la.matrix_rank(A)
print(rank)  # 输出: 1 (因为矩阵是奇异的)

7.3 伪逆

对于非方阵或奇异矩阵,可用 la.pinv() 计算伪逆。

A = np.array([[1, 2], [3, 4]])
A_pinv = la.pinv(A)
print(A_pinv)
# 输出:
# [[-2.   1. ]
#  [ 1.5 -0.5]]

8. 注意事项

  1. 矩阵 vs 数组
  • NumPy 推荐使用 ndarray 而不是 numpy.matrix,因为 ndarray 更通用,matrix 类的特殊行为(如 * 表示矩阵乘法)可能导致混淆。
  • 使用 @ 运算符和 np.dot() 可以完全替代 matrix 类的矩阵乘法。
  1. 数值稳定性
  • 对于接近奇异的矩阵(如行列式接近 0),la.inv()la.solve() 可能因数值误差导致不准确。
  • 使用 SVD 或伪逆可以处理这类情况。
  1. 性能
  • 大矩阵运算可能需要优化,考虑使用稀疏矩阵(scipy.sparse)或并行计算。
  1. 输入要求
  • 许多 linalg 函数要求输入是二维数组(矩阵)或一维数组(向量),需确保形状正确。

9. 示例:综合应用

假设要分析一个线性系统,计算其特征值、解方程组并验证结果:

# 定义矩阵和向量
A = np.array([[4, -1], [2, 1]])
b = np.array([1, 2])

# 求解线性方程组 Ax = b
x = la.solve(A, b)
print("解 x:", x)  # 输出: [0.5 1. ]

# 计算特征值和特征向量
eigvals, eigvecs = la.eig(A)
print("特征值:", eigvals)
print("特征向量:\n", eigvecs)

# 验证解
print("验证 Ax:", A @ x)  # 输出: [1. 2.] (与 b 一致)

10. 总结

  • numpy.linalg 提供了全面的线性代数工具,涵盖矩阵运算、方程求解、特征值分析和矩阵分解。
  • 核心函数包括 la.inv()la.solve()la.eig()la.svd() 等。
  • 推荐使用 ndarray 而非 numpy.matrix,因为前者更灵活且是 NumPy 的核心数据结构。
  • 注意数值稳定性、输入格式和性能优化,确保代码高效且正确。

如果有具体线性代数问题或需要更详细的示例,请告诉我!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注