2017-02-06 26 views
0
import numpy as np 
from scipy import linalg as linalg 
M = np.array([[1,2],[2,1],[3,4],[4,3]]) 
Evals, Evecs = linalg.eigh(M.T.dot(M)) 
EvecShape = Evecs.shape 
print Evals 
print Evecs 
ncols = EvecShape[1] 
for i in range(ncols/2): 
    Evals[i], Evals[ncols-1-i] = Evals[ncols-1-i], Evals[i] 
    Evecs[:,i], Evecs[:,ncols-1-i] = Evecs[:,ncols-1-i], Evecs[:,i] 
print Evals 
print Evecs 

我想计算MT * M的特征值和特征向量,并通过交换相应的列以降序排列特征值。打印结果如下:交换np.array的两列时发生了什么?

[ 2. 58.] 
[[-0.70710678 0.70710678] 
[ 0.70710678 0.70710678]] 
[ 58. 2.] 
[[ 0.70710678 0.70710678] 
[ 0.70710678 0.70710678]] 

看来我没有交换Evals中的元素。但对Evecs而言,显然有些事情是错误的。任何人都可以告诉我这里发生了什么?

回答

1

您的代码的问题是,当您尝试交换列时,您在读出第一列之前先用另一列覆盖另一列。这是因为如果可能的话,数组切片不会复制数据,而是引用切片数组的缓冲区。

为了减轻您可以

  • 力使用.copy()副本,像这样

Evecs[:,i], Evecs[:,ncols-1-i] = Evecs[:,ncols-1-i], Evecs[:,i].copy() 

  • 避免环路,只是做

Evecs = Evecs[:, ::-1] 
1

您正在尝试排序像二维数组这样的特征向量。不好。使用特定的方法。下面在这里;

import numpy as np 
from scipy import linalg as linalg 
M = np.array([[1,2],[2,1],[3,4],[4,3]]) 
Evals, Evecs = linalg.eigh(M.T.dot(M)) 
print Evals 
print Evecs 

index = Evals.argsort()[::-1] 

Evals= Evals[index] 
Evecs = Evecs [:,index] 

print Evals 
print Evecs