应优先使用np.linalg.eigh():它专为实对称/厄米特矩阵设计,返回实数特征值和正交归一化特征向量,计算更快更稳定;而eig()对实对称矩阵仍返回复数特征值且不保证特征向量正交。

用 numpy.linalg.eig 计算实对称矩阵的特征值和特征向量
实对称矩阵(如协方差矩阵、拉普拉斯矩阵)用 numpy.linalg.eig 没问题,但结果中特征向量不正交归一化,且特征值是复数类型(即使输入为实数),容易误判。若只关心数值精度和速度,eig 足够;但若后续要验证 A @ v == λ * v 或做 PCA,建议优先用 eigh。
-
eig返回的是(eigenvalues, eigenvectors)元组,其中eigenvectors[:, i]对应第i个特征值,不是行向量 - 特征向量按列存储,每列是单位向量(已归一化),但不保证正交——除非矩阵严格对称(浮点误差可能导致
A.T != A) - 若输入是
float64实矩阵,eig仍返回complex128特征值,需用.real提取(但可能掩盖非对称导致的虚部)
实对称/厄米特矩阵必须用 numpy.linalg.eigh
只要矩阵数学上是对称的(或复数域下的厄米特),就该无条件选 eigh:它强制利用对称性,计算更快、更稳定,且返回实数特征值和正交归一化的特征向量。
-
eigh自动检测并利用对称性,比eig快约 2–3 倍,尤其在n > 1000时差异明显 - 返回的特征值是
float64类型,无需.real过滤;特征向量矩阵满足V.T @ V == I(数值上接近单位阵) - 注意:它只读取下三角(或上三角)部分,因此即使你传入
A + A.T修正过的矩阵,也建议先用np.triu(A) + np.tril(A, -1).T显式对称化,避免底层优化误判
遇到 LinAlgError: Eigenvalues did not converge 怎么办
这个错误通常不是因为矩阵奇异,而是数值病态:特征值间距过小、矩阵严重非对称、或含极大极小混合量级的元素(如同时有 1e-15 和 1e8)。
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
- 先检查对称性:
np.allclose(A, A.T, atol=1e-10),不满足就别硬用eigh - 尝试预处理:对矩阵做相似变换,例如用
np.diag(1/np.sqrt(np.diag(A))) @ A @ np.diag(1/np.sqrt(np.diag(A)))(对角缩放),缓解条件数问题 - 若只需前
k个最大特征值,改用scipy.sparse.linalg.eigsh(配合which='LM'),它基于 Arnoldi 迭代,对大型稀疏矩阵更鲁棒
特征向量方向不确定?这是正常现象
NumPy 不保证特征向量符号一致性——同一矩阵多次调用 eig 或 eigh,可能得到相反方向的向量(比如 [0.707, -0.707] 和 [-0.707, 0.707] 都合法)。这在 PCA、谱聚类等场景中常被忽略,导致结果不可复现。
立即学习“Python免费学习笔记(深入)”;
- 标准化做法:对每个特征向量,强制让第一个非零元为正,用
v *= np.sign(v[np.argmax(np.abs(v))]) - 若用于跨进程/跨机器比较,必须加这步;否则仅作中间计算可跳过
- 注意:该操作不改变正交性或特征方程成立性,只是约定方向
数值稳定性与方向约定这两点,实际项目里最容易被跳过,但恰恰是调试周期拉长的主因。

















