正确调用 np.linalg.svd(A) 默认返回 U、S、Vh,其中 Vh 是右奇异向量的共轭转置(非 V);S 为一维数组,重建需用 np.diag(S) 或广播乘法;设 full_matrices=False 可得经济型分解,更省内存且常用。

怎样用 numpy.linalg.svd 正确分解矩阵并拿到 U、S、Vh
numpy.linalg.svd 默认返回三个对象:左奇异向量矩阵 U(m×m 正交)、奇异值数组 S(长度为 min(m,n) 的一维数组)、右奇异向量共轭转置 Vh(n×n 正交)。注意它不返回 V,而是 Vh(即 V.T.conj()),这点容易搞反。
- 直接调用
U, S, Vh = np.linalg.svd(A)即可,无需额外参数 -
S是一维ndarray,不是对角矩阵;如需构造Σ,得手动用np.diag(S)或更稳妥的np.zeros((m,n)); np.fill_diagonal(Σ, S) - 若只关心前
k个奇异值和向量,加参数full_matrices=False,此时U为m×k、Vh为k×n,节省内存且更常用
为什么 U @ np.diag(S) @ Vh 有时不等于原矩阵 A
这不是函数出错,而是浮点精度 + 形状/类型不匹配导致的常见假失败:
- 检查
A.dtype是否为float64或complex128;如果A是整数型(如int32),svd会静默转为float64,但重建时若没显式转换可能引发广播错误 - 确保矩阵维度对齐:
U.shape[1] == len(S),且Vh.shape[0] == len(S);full_matrices=True(默认)时三者尺寸必须满足(m,m)×(min(m,n),)×(n,n) - 重建应写成:
U[:, :len(S)] @ np.diag(S) @ Vh[:len(S), :](尤其在full_matrices=False下更安全) - 用
np.allclose(U @ np.diag(S) @ Vh, A)判断,别用==
linalg.svd 的 compute_uv 和 hermitian 参数怎么选
这两个参数控制计算范围和算法路径,影响性能与适用性:
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
-
compute_uv=False:只返回S,跳过U和Vh计算,适合只需要奇异值(如判断矩阵秩、条件数)的场景,速度明显提升 -
hermitian=True:仅当A是实对称或复共轭对称(Hermitian)时设置;此时调用更高效的对称特征值求解器,U和Vh将相同(实对称时Vh == U.T),但若误设会导致结果错误甚至报错 - 大多数普通矩阵保持默认(
compute_uv=True,hermitian=False)即可
从 SVD 结果还原原始矩阵时最容易漏掉的两件事
- 忘记
S是一维数组,直接写U @ S @ Vh会触发ValueError: matmul: Input operand 1 has a mismatch in its core dimension;必须显式转成对角阵或用np.einsum - 忽略复数矩阵的共轭:若
A是复数,Vh已是V.conj().T,重建时不能再额外调用.conj()或.T,否则会翻倍取共轭,破坏正交性
实际中,只要记住 svd 返回的是“标准数学定义下的分解”——即 A = U Σ Vh,其中 Vh 是 V 的共轭转置,其余都是围绕这个关系做形状适配和数值处理。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










