为何numpy中两种矩阵特征值计算方法的运行速度差异显著?
为什么相似变换操作比直接调用
eigvals更快? 首先要戳破核心误解:你测试的两个操作完全不是一回事,这是你觉得矛盾的根本原因:
np.linalg.eigvals(D)是从零开始求解矩阵D的所有特征值,这是一个复杂的数值计算任务,底层用QR迭代这类算法,需要处理收敛性、数值稳定性等问题,看似是O(n³)复杂度,但实际包含大量迭代、正交化等额外开销。- 而
eigenvectors@D@np.linalg.inv(eigenvectors)是用已经提前算好的特征向量对D做相似对角化,你的%timeit只测了这一步的耗时,完全没把之前计算eigenvectors的时间算进去——你已经通过np.linalg.eig(D)预先得到了特征向量,这一步只是对已有结果做矩阵运算。
速度差异的具体原因
- 任务复杂度天差地别:特征值计算是迭代求解的过程,需要不断调整矩阵直到收敛到特征值,过程中涉及大量正交化、移位操作,计算成本远高于单纯的矩阵乘法和求逆。
- 矩阵运算的极致优化:矩阵乘法(
@)和求逆(np.linalg.inv)都是调用了底层BLAS/LAPACK的高度优化实现,这些操作的O(n³)是“纯粹”的浮点运算,没有特征值计算里的迭代收敛开销。
已知特征向量的情况怎么理解
如果已经有了可靠的特征向量,确实不需要再调用eigvals:相似对角化后的矩阵对角元就是特征值,直接取np.diag(eigenvectors@D@np.linalg.inv(eigenvectors))就能拿到结果。这时候的耗时确实比从头算特征值小——因为你跳过了最耗时的特征向量求解和特征值迭代收敛步骤,只需要做几次矩阵运算。
但要注意:特征向量的计算和特征值计算是绑定在一起的,np.linalg.eig在算特征值的同时也会算出特征向量,两者的计算成本大部分是重叠的。如果是从无到有,先算特征向量再做变换的总耗时,肯定比直接调用eigvals更长——你可以把整个流程放进%timeit验证:
%timeit evals, evecs = np.linalg.eig(D); np.diag(evecs@D@np.linalg.inv(evecs))
内容的提问来源于stack exchange,提问作者ABZANMASTER
相关产品推荐
相关产品推荐

