ordenar valores propios y vectores propios asociados después de usar numpy.linalg.eig en python

94

Estoy usando numpy.linalg.eig para obtener una lista de autovalores y autovectores:

A = someMatrixArray
from numpy.linalg import eig as eigenValuesAndVectors

solution = eigenValuesAndVectors(A)

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

Me gustaría ordenar mis valores propios (por ejemplo, de menor a mayor), de una manera que sepa cuál es el vector propio asociado después de la clasificación.

No encuentro ninguna forma de hacer eso con las funciones de Python. ¿Hay alguna forma sencilla o tengo que codificar mi versión de clasificación?

Jorge Leitao
fuente

Respuestas:

153

Utilice numpy.argsort . Devuelve los índices que se usarían para ordenar la matriz.

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 los valores propios son complejos, el orden de clasificación es lexicográfico (es decir, los números complejos se ordenan primero según su parte real, con los lazos rotos por su parte imaginaria).

unutbu
fuente
27
Por cierto, es más común ordenar de mayor a menor valor propio. uso justo: idx = eigenValues.argsort()[::-1].
Carl F.
5
para obtener k valores propios más grandes k = 2 idx = eigenValues.argsort () [- k:] [:: - 1]
mrgloom
3
Para k = 1 se puede usareigenVectors[:, eigenValues.argmax()]
utapyngo
1
@MaxNoe: Según los documentos , "Los valores propios no están necesariamente ordenados".
unutbu
2
Ah, estaba usando ocho: los valores propios en orden ascendente, cada uno repetido según su multiplicidad.
MaxNoe
6

La respuesta anterior de unutbu es muy clara y concisa. Pero, aquí hay otra forma en que podemos hacerlo, que es más general y también se puede usar para listas.

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)

Este tup [0] es el valor propio en función del cual la función de clasificación clasificará la lista.

reverse = False es para orden creciente.

ShikharDua
fuente
1

El fragmento de código de ubuntu no funciona en mi Python 3.6.5. Conduce errores en tiempo de ejecución. Entonces, refactoricé su código a este que funciona bien en mis casos de prueba:

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)
enfoque estándar
fuente