简体   繁体   中英

Python Numpy eigen vectors sort error

I am currently trying to sort a tuple a list of tuples by their first value, but I am getting an error:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Here is my code:

def eigen_calc(S):
    eig_val, eig_vec = LA.eig(S)

    eig_pairs = [(np.abs(eig_val[i]), eig_vec[:, i]) for i in range(len(eig_val))]

    eig_pairs.sort(reverse=True)

where the input S is my empirical covariance matrix with the dimensions (21, 21) .

You could do this by passing the key= keyword argument to the sort method:

eig_pairs.sort(reverse=True, key=(lambda x: x[0]))

That lambda function just grabs the first element from each (eig_val, eig_vec) pair, meaning that the tuples are sorted by descending order of eigenvalue magnitude.


It's generally much faster to deal with numpy arrays directly, rather than converting to plain Python objects such as lists and tuples.

A much better solution would be to simply call np.argsort to get the indices of the eigenvalues in ascending order of magnitude, reverse the order of the indices, then use them to index into the vector of eigenvalues and the columns of the matrix of eigenvectors:

# get the array of indices that would sort `eig_val` in ascending order of 
# magnitude
asc_order = np.argsort(np.abs(eig_val))

# reverse the order of the indices using slice indexing
desc_order = asc_order[::-1]

# sort eigenvalues and eigenvectors using this index array
sorted_eig_val = eig_val[desc_order]
sorted_eig_vec = eig_vec[:, desc_order]

Another minor point: if S is a covariance matrix then it should be symmetric, so you can use np.linalg.eigh , which is faster for Hermitian or symmetric matrices than np.linalg.eig .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM