5

I am using linalg.eig(A) to get the eigenvalues and eigenvectors of a matrix. Is there an easy way to sort these eigenvalues (and associated vectors) in order?

user1220022
  • 11,167
  • 19
  • 41
  • 57
  • Possible duplicate: http://stackoverflow.com/questions/8092920/sort-eigenvalues-and-associated-eigenvectors-after-using-numpy-linalg-eig-in-pyt – amcnabb May 07 '13 at 17:58
  • If the matrix is real and symmetric (or complex and Hermitian), `linalg.eigh()` returns the real eigenvalues in ascending order. https://numpy.org/doc/stable/reference/generated/numpy.linalg.eigh.html – Jack Valmadre Mar 13 '21 at 19:45

2 Answers2

7

You want to use the NumPy sort() and argsort() functions. argsort() returns the permutation of indices needed to sort an array, so if you want to sort by eigenvalue magnitude (the standard sort for NumPy arrays seems to be smallest-to-largest), you can do:

import numpy as np

A = np.asarray([[1,2,3],[4,5,6],[7,8,9]])
eig_vals, eig_vecs = np.linalg.eig(A)

eig_vals_sorted = np.sort(eig_vals)
eig_vecs_sorted = eig_vecs[:, eig_vals.argsort()]


# Alternatively, to avoid making new arrays
# do this:

sort_perm = eig_vals.argsort()

eig_vals.sort()     # <-- This sorts the list in place.
eig_vecs = eig_vecs[:, sort_perm]
ely
  • 74,674
  • 34
  • 147
  • 228
  • 7
    In your second example, no need to call sort() on eig_vals again, you already have sort_perm. i.e. eig_vals = eig_vals[sort_perm] – user545424 Apr 10 '12 at 16:25
  • Good point! I wasn't sure whether using the slice notation `[]` made an extra copy of the list. My thinking was that at least one of them can be done in place, and I didn't know if `a = a[sort_perm]` is as efficient as `a.sort()`. – ely Apr 10 '12 at 19:18
  • 2
    The eig_vecs are column vectors, so it should be eig_vecs[:, eig_vals.argsort()], right? – amcnabb May 07 '13 at 18:18
  • 1
    @denvar Thanks -- I fixed the typo. – ely May 10 '16 at 19:12
-3

np.linalg.eig will often return complex values. You may want to consider using np.sort_complex(eig_vals).

Ozgur Vatansever
  • 49,246
  • 17
  • 84
  • 119
Troy
  • 1