Python用NumPy求矩阵的逆:np.linalg.inv基础用法

小石头
小石头
发布时间:2026-10-22 | 6人浏览过
原创
在NumPy中,计算方阵逆矩阵的标准方法是使用线性代数子模块下的 np.linalg.inv() 函数。调用时只需传入一个二维方阵,该函数就会返回对应的逆矩阵;如果矩阵不可逆或形状不满足方阵要求,程序将抛出 LinAlgError 异常。

一、矩阵逆运算的基本原理与NumPy接口

在数学上,设 $A$ 是一个 $n \times n$ 的方阵,若存在一个矩阵 $A^{-1}$ 使得 $A \cdot A^{-1} = A^{-1} \cdot A = I$(其中 $I$ 为 $n$ 阶单位矩阵),则称 $A$ 是可逆矩阵,$A^{-1}$ 即为 $A$ 的逆矩阵。

NumPy 将求逆功能封装在 numpy.linalg.inv(a) 中。传入参数 a 必须是包含浮点数或复数类型的方阵(最后两个维度相等且至少为2维)。求解过程底层调用了 LAPACK 库的高性能数值算法(通常基于 LU 分解),兼具执行效率与数值稳定性。

Python用NumPy求矩阵的逆:np.linalg.inv基础用法
图 1:NumPy 矩阵求逆接口的映射关系与验算闭环结构

二、标准调用步骤与代码实操

使用 np.linalg.inv() 求逆的基本流程分为三个环节:准备并定义输入方阵、调用接口获取逆矩阵、对计算结果进行浮点精度验证。

步骤一:定义合法的二维方阵

首先导入 NumPy 模块,并使用 np.array() 构建目标方阵。这里以一个 $2 \times 2$ 的整型方阵为例:

import numpy as np

# 定义一个 2x2 矩阵
A = np.array([[4.0, 7.0],
              [2.0, 6.0]])
print("原矩阵 A:\n", A)
print("形状:", A.shape)

示例输出:

原矩阵 A:
 [[4. 7.]
 [2. 6.]]
形状: (2, 2)

步骤二:调用 np.linalg.inv 求逆

直接将方阵 A 传入 np.linalg.inv(),得到返回的逆矩阵数组:

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

示例输出:

A 的逆矩阵:
 [[ 0.6 -0.7]
 [-0.2  0.4]]

步骤三:验算求逆结果

理论上,原矩阵与逆矩阵相乘 A @ A_inv 结果应严格等于单位矩阵 np.eye(2)。但在计算机内部,由于双精度浮点数舍入误差的存在,部分非对角元素可能为接近于 0 的极小浮点数(如 1e-17),而不会严格等于 0.0。因此,严禁使用 == 判断相等,必须使用 np.allclose() 进行容差比较:

# 矩阵乘法验证
product = A @ A_inv
identity = np.eye(2)

print("A @ A_inv 乘积:\n", product)

# 使用 np.allclose 校验,允许浮点容差
is_valid = np.allclose(product, identity)
print("验算是否为单位矩阵:", is_valid)  # 输出 True
Python用NumPy求矩阵的逆:np.linalg.inv基础用法
图 2:np.linalg.inv 方阵求逆操作执行四步流程图

三、常见错误与前置条件判定

调用 np.linalg.inv() 时,最常见的两种运行期错误都属于 np.linalg.LinAlgError 异常:

1. 形状错误:传入非方阵

求逆运算在数学上仅对方阵定义。如果传入的数组最后两个维度不一致(例如 $2 \times 3$ 矩阵),NumPy 会立刻抛出错误:

non_square = np.array([[1.0, 2.0, 3.0],
                       [4.0, 5.0, 6.0]])
try:
    np.linalg.inv(non_square)
except np.linalg.LinAlgError as e:
    print("捕获错误:", e)

报错信息示例:

捕获错误: Last 2 dimensions of the array must be square

2. 奇异矩阵(不可逆矩阵)错误

即使矩阵是方阵,如果其行列式等于 0(或者矩阵存在线性相关的行/列),该矩阵被称为“奇异矩阵”(Singular Matrix),数学上没有逆矩阵。此时 np.linalg.inv() 无法求解:

singular_matrix = np.array([[1.0, 2.0],
                            [2.0, 4.0]]) # 第二行是第一行的2倍
try:
    np.linalg.inv(singular_matrix)
except np.linalg.LinAlgError as e:
    print("捕获错误:", e)

报错信息示例:

捕获错误: Singular matrix
工程建议:当遇到非方阵或奇异矩阵时,如果业务场景允许最小二乘近似解,可以使用摩尔-彭罗斯广义逆函数 np.linalg.pinv(A)(Pseudo-inverse),它能在矩阵不可逆时返回数值上稳定的伪逆矩阵。
Python用NumPy求矩阵的逆:np.linalg.inv基础用法
图 3:NumPy 矩阵求逆调用判定逻辑与错误分支决策图

四、批量求逆技巧(高维数组广播)

np.linalg.inv() 原生支持高维张量的批量求逆。当输入数组的维度大于 2 时,NumPy 会将前面的维度视为“批次索引”(Batch Dimensions),只对最后两个维度 (..., N, N) 分别执行求逆操作。

# 构造形状为 (3, 2, 2) 的批次方阵,代表 3 个 2x2 方阵
batch_A = np.array([
    [[1.0, 2.0], [3.0, 4.0]],
    [[5.0, 2.0], [2.0, 1.0]],
    [[3.0, 0.0], [0.0, 2.0]]
])

# 一次性对全部 3 个方阵求逆
batch_inv = np.linalg.inv(batch_A)
print("批次求逆结果形状:", batch_inv.shape)  # 输出: (3, 2, 2)

# 批量验证 A @ A_inv 是否全为单位矩阵
batch_identity = batch_A @ batch_inv
all_correct = np.allclose(batch_identity, np.eye(2))
print("批量验算一致性:", all_correct)  # 输出: True

这种矢量化批处理方式避免了 Python 层的 for 循环,在处理海量小方阵求逆(如卡尔曼滤波、三维变换矩阵堆叠)时性能大幅提升。

五、实际应用中的性能与替代方案

在工程实践中,求逆矩阵最常见的目的是为了求解线性方程组 $Ax = b$。初学者往往习惯写成:

# 不推荐:先显式求逆再做乘法
x = np.linalg.inv(A) @ b

但这种写法在数值分析中通常不被推荐,原因如下:

  • 运算量翻倍:显式计算 $A^{-1}$ 再乘向量需要先完成矩阵求逆再做矩阵-向量乘法,耗时明显高于直接解方程。
  • 累积误差更大:显式求逆过程会放大病态矩阵(高条件数矩阵)的浮点舍入误差。

正确的替代方案是直接使用 np.linalg.solve(A, b):

# 推荐:直接求解线性方程组 Ax = b
x = np.linalg.solve(A, b)

np.linalg.solve() 内部利用高斯消元法或 LU 分解直接求出未知向量 $x$,不仅速度更快,而且在数值上更加稳定。

Python用NumPy求矩阵的逆:np.linalg.inv基础用法
图 4:NumPy 矩阵求逆核心知识点与工程决策综合归纳图

六、知识梳理与核心要点总结

功能 / 问题 代码或判断方法 注意事项
标准矩阵求逆 np.linalg.inv(A) 输入必须为非奇异方阵,数据类型通常为浮点数
结果正确性验算 np.allclose(A @ A_inv, np.eye(n)) 计算机存在浮点舍入微小误差,切忌使用 == 比较
长方阵或奇异矩阵 np.linalg.pinv(A) 当原矩阵不可逆时,使用广义逆(SVD分解)获取数值解
求解线性方程 $Ax=b$ np.linalg.solve(A, b) 比 inv(A) @ b 速度更快、精度更高,应作为首选
多方阵批处理 输入形状为 (..., N, N) NumPy 会自动在批次维度上广播运算,无需编写循环

掌握 np.linalg.inv() 的关键在于明确其“方阵且满秩”的前置要求,养成用 np.allclose() 检验计算结果的习惯,并在实际求解方程组时合理选用 solve(),从而在保证算法正确性的同时兼顾数值稳定性与计算效率。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表