NumPy 实现矩阵的逆运算

3 阅读3分钟

一、矩阵逆运算的基础认知

首先要明确:只有方阵(行数=列数)且行列式≠0的矩阵才有逆矩阵(这类矩阵称为“非奇异矩阵”)。逆矩阵的核心作用是求解线性方程组(如 Ax=bx=A1bAx=b → x=A^{-1}b)、特征分解等,是 AI 中线性代数运算的基础。

二、NumPy 实现矩阵逆运算的完整步骤

1. 前置准备

确保已导入 NumPy(常规简写为 np):

import numpy as np

2. 核心函数:np.linalg.inv()

语法:np.linalg.inv(matrix)

  • 参数:matrix 必须是二维方阵(如 2×2、3×3),且行列式≠0;
  • 返回值:输入矩阵的逆矩阵;
  • 异常:若矩阵非方阵/行列式=0,会抛出 LinAlgError

3. 实操示例(基础版)

# 1. 定义一个2×2的非奇异矩阵(行列式≠0)
A = np.array([[1, 2], 
              [3, 4]])
print("原始矩阵A:\n", A)

# 2. 计算逆矩阵
A_inv = np.linalg.inv(A)
print("\nA的逆矩阵A_inv:\n", A_inv)

# 3. 验证:原矩阵 × 逆矩阵 = 单位矩阵(浮点误差可忽略)
identity = A @ A_inv  # 矩阵乘法,等价于np.matmul(A, A_inv)
print("\nA × A_inv(验证单位矩阵):\n", identity)

输出结果

原始矩阵A:
 [[1 2]
 [3 4]]

A的逆矩阵A_inv:
 [[-2.   1. ]
 [ 1.5 -0.5]]

A × A_inv(验证单位矩阵):
 [[1.00000000e+00 0.00000000e+00]
 [1.11022302e-16 1.00000000e+00]]

4. 进阶示例:3×3矩阵逆运算+求解线性方程组

逆矩阵最典型的应用是求解线性方程组 Ax=bAx = b,步骤:x=A1bx = A^{-1}b

# 定义3×3系数矩阵A(非奇异)
A = np.array([[1, 2, 3],
              [4, 5, 6],
              [7, 8, 10]])
# 定义常数项向量b
b = np.array([6, 15, 27])

# 步骤1:计算A的逆矩阵
A_inv = np.linalg.inv(A)
print("A的逆矩阵:\n", A_inv)

# 步骤2:求解x = A_inv × b
x = A_inv @ b
print("\n线性方程组的解:x={}, y={}, z={}".format(x[0], x[1], x[2]))

# 验证:A × x 应等于 b
verify = A @ x
print("\n验证A×x = b:", verify)  # 输出[ 6. 15. 27.],与b一致

三、关键注意事项(避坑核心)

1. 仅方阵能求逆,非方阵需用伪逆

  • 错误场景:对2×3矩阵调用 np.linalg.inv(),会直接报错;
  • 解决方案:非方阵用伪逆np.linalg.pinv()),适用于线性回归等场景:
    # 非方阵(2×3)求伪逆
    B = np.array([[1, 2, 3], 
                  [4, 5, 6]])
    B_pinv = np.linalg.pinv(B)
    print("非方阵B的伪逆:\n", B_pinv)
    

2. 行列式=0的矩阵(奇异矩阵)无法求逆

  • 原因:奇异矩阵的行/列线性相关,无逆矩阵;
  • 规避方法:先计算行列式,判断是否非0后再求逆:
    # 定义奇异矩阵(行列式=0)
    C = np.array([[1, 2], 
                  [2, 4]])  # 第二行是第一行的2倍,线性相关
    
    # 步骤1:计算行列式
    det_C = np.linalg.det(C)
    print("矩阵C的行列式:", det_C)  # 输出0.0
    
    # 步骤2:判断是否可求逆
    if np.isclose(det_C, 0):  # 浮点误差,用isclose判断是否≈0
        print("矩阵C是奇异矩阵,无法求逆!")
        # 可选:用伪逆替代
        C_pinv = np.linalg.pinv(C)
        print("矩阵C的伪逆:\n", C_pinv)
    else:
        C_inv = np.linalg.inv(C)
        print("矩阵C的逆矩阵:\n", C_inv)
    

3. 浮点精度问题

  • 现象:逆矩阵与原矩阵相乘后,对角线可能出现 1.00000000000000021e-16 级别的误差;
  • 本质:浮点数运算的正常误差,不影响实际使用;
  • 优化:可通过 np.round() 保留指定小数位:
    identity = A @ A_inv
    identity_rounded = np.round(identity, decimals=6)  # 保留6位小数
    print("四舍五入后的单位矩阵:\n", identity_rounded)
    

4. 大数据矩阵求逆效率

  • 问题:对1000×1000以上的大矩阵求逆,耗时且占内存;
  • 解决方案:
    1. 优先用 np.linalg.solve() 替代逆运算(求解 Ax=bAx=b 时,solveinv 快且稳定);
    2. 大矩阵分块处理,或用稀疏矩阵(scipy.sparse)。

四、替代方案:np.linalg.solve() 更高效求解方程组

虽然逆矩阵能解 Ax=bAx=b,但 NumPy 官方推荐用 np.linalg.solve()——它无需显式计算逆矩阵,直接求解,效率更高、数值稳定性更好:

# 求解Ax = b,对比inv和solve
A = np.array([[1, 2], [3, 4]])
b = np.array([5, 11])

# 方法1:逆矩阵求解
x1 = np.linalg.inv(A) @ b
# 方法2:solve直接求解(推荐)
x2 = np.linalg.solve(A, b)

print("inv求解结果:", x1)  # [1. 2.]
print("solve求解结果:", x2)  # [1. 2.],与x1一致,但效率更高