108 votes

Trier les valeurs propres et les vecteurs propres associés après avoir utilisé numpy.linalg.eig en python

Je suis en train d'utiliser numpy.linalg.eig pour obtenir une liste de valeurs propres et de vecteurs propres :

A = someMatrixArray
from numpy.linalg import eig as eigenValuesAndVectors

solution = eigenValuesAndVectors(A)

eigenValues = solution[0]
eigenVectors = solution[1]

Je voudrais trier mes valeurs propres (par exemple, du plus bas au plus haut), de manière à savoir quel est le vecteur propre associé après le tri.

Je ne trouve aucun moyen de le faire avec des fonctions python. Existe-t-il un moyen simple ou dois-je coder ma propre version de tri ?

176voto

unutbu Points 222216

Utilisez numpy.argsort. Cela renvoie les indices que l'on utiliserait pour trier le tableau.

import numpy as np
import numpy.linalg as linalg

A = np.random.random((3,3))
eigenValues, eigenVectors = linalg.eig(A)

idx = eigenValues.argsort()[::-1]   
eigenValues = eigenValues[idx]
eigenVectors = eigenVectors[:,idx]

Si les valeurs propres sont complexes, l'ordre de tri est lexicographique (c'est-à-dire que les nombres complexes sont triés en fonction de leur partie réelle en premier, avec les liens brisés par leur partie imaginaire).

27 votes

Soit dit en passant, il est plus courant de trier de la plus grande à la plus petite valeur propre. utilisez simplement: idx = eigenValues.argsort()[::-1].

6 votes

Pour obtenir les k plus grandes valeurs propres k=2 idx = eigenValues.argsort()[-k:][::-1]

3 votes

Pour k=1, on peut utiliser eigenVectors[:, eigenValues.argmax()]

6voto

ShikharDua Points 356

La réponse ci-dessus par unutbu est très claire et concise. Mais voici une autre façon de le faire qui est plus générale et peut être utilisée pour les listes également.

eval, evec =  sp.eig(A)
ev_list = zip( eval, evec )
ev_list.sort(key=lambda tup:tup[0], reverse=False)
eval, evec = zip(*ev_list)

Ce tup[0] est la valeur propre en fonction de laquelle la fonction de tri triera la liste.

reverse = False est pour un ordre croissant.

3voto

std.approach Points 31

Le code d'Ubuntu ne fonctionne pas sur mon Python 3.6.5. Cela entraîne des erreurs d'exécution. J'ai donc refactorisé son code pour obtenir celui-ci qui fonctionne correctement sur mes cas de test :

import numpy as np
from numpy import linalg as npla
#
def eigen(A):
    eigenValues, eigenVectors = npla.eig(A)
    idx = np.argsort(eigenValues)
    eigenValues = eigenValues[idx]
    eigenVectors = eigenVectors[:,idx]
    return (eigenValues, eigenVectors)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X