numpy.linalg.solve最稳妥,仅适用于方阵且系数矩阵可逆;否则用lstsq求最小二乘解,返回四元组,首项为解。

用 numpy.linalg.solve 直接求解最稳妥
只要方程组是方阵且系数矩阵可逆(即满秩),numpy.linalg.solve 就是最直接、最推荐的方式。它底层调用 LAPACK 的 DGESV,数值稳定、速度快,且自动处理浮点精度问题。
常见错误是把系数和常数项拼成一个大矩阵再“手动消元”,这既没必要又容易出错;还有人误用 numpy.linalg.inv 先求逆再乘,这在病态矩阵下会显著放大误差。
- 系数矩阵
A必须是二维ndarray,形状为(n, n);常数向量b是一维ndarray,长度为n - 如果
A奇异(行列式≈0),solve会抛出LinAlgError: Singular matrix,不能静默返回错误结果 - 示例:
import numpy as np A = np.array([[2, 1, -1], [-3, -1, 2], [-2, 1, 2]]) b = np.array([8, -11, -3]) x = np.linalg.solve(A, b) # 返回 array([2., 3., -1.])
当系数矩阵不是方阵时,改用 numpy.linalg.lstsq
欠定(未知数多于方程)或超定(方程多于未知数)系统无法用 solve,这时本质是在求最小二乘解。注意:lstsq 默认返回的是最小二乘意义下的最优解,不保证精确满足所有方程(除非方程组本身相容)。
容易忽略的点:它的返回值是四元组,真正需要的只是第一个元素 x;第二个是残差平方和,仅当解存在且唯一时才有意义;第三、四个是秩和奇异值,用于诊断矩阵病态程度。
立即学习“Python免费学习笔记(深入)”;
调用 Cutout.Pro 视觉处理 API 进行背景移除、人像抠图和照片增强,支持文件上传与图片 URL 输入。
- 输入
A可以是任意形状(m, n),b是(m,)或(m, 1) - 若
m (欠定),它返回的是所有最小二乘解中范数最小的那个(即 Moore–Penrose 伪逆解) - 示例(超定):
A = np.array([[1, 2], [2, 3], [3, 4]]) b = np.array([1, 2, 3]) x, residuals, rank, s = np.linalg.lstsq(A, b, rcond=None) # x ≈ array([-0.5, 0.5]),residuals 是标量残差平方和
验证解是否靠谱,别只看 np.allclose(A @ x, b)
浮点计算总有误差,直接用 == 比较必然失败;但仅用 np.allclose 也不够——它默认容忍相对误差 1e-05 和绝对误差 1e-08,对病态系统可能掩盖严重偏差。
更务实的做法是同时检查残差范数和条件数:np.linalg.cond(A) 超过 1e12 就说明矩阵严重病态,此时即使 A @ x 看似接近 b,解 x 也可能完全不可信。
- 计算残差:
res = np.linalg.norm(A @ x - b),和np.linalg.norm(b)对比,看相对残差是否在预期量级(比如 - 如果
cond(A)很大,优先考虑重新参数化问题,或换用正则化(如np.linalg.lstsq的rcond参数) - 不要依赖
np.isclose逐元素判断,它对向量整体误差不敏感
符号解?NumPy 不干这事,该上 sympy
NumPy 是数值计算库,所有运算都在浮点域进行。如果你需要带变量的解析解、分式表达、或严格零判断(比如系数含 π 或 √2),numpy.linalg.solve 会立刻转成浮点近似,丢失代数结构。
这时候必须切到符号计算:用 sympy.Matrix 构造增广矩阵,调用 rref() 或 linsolve()。虽然慢,但结果可导出 LaTeX、可代入任意精度数值、可判断自由变量个数。
- 示例:
from sympy import symbols, Matrix x, y, z = symbols('x y z') A = Matrix([[1, 1, 1], [2, -1, 1], [1, 2, -1]]) b = Matrix([6, 3, 2]) sol = A.LUsolve(b) # 返回 Matrix([[1], [2], [3]]) - 混合使用场景:先用 SymPy 推导通解形式,再用 NumPy 做大批量数值代入
数值求解线性方程组真正的难点不在调哪个函数,而在于提前识别矩阵是否病态、是否相容、是否需要正则化——这些判断比写一行 solve 花的时间多得多。

















