Tengo una lista numérica:
myList = [1, 2, 3, 100, 5]
Ahora si ordeno esta lista para obtener [1, 2, 3, 5, 100]. Lo que quiero son los índices de los elementos de la lista original en el orden ordenado, es decir, [0, 1, 2, 4, 3]
la función de clasificación de ala MATLAB que devuelve valores e índices.

Respuestas:
Si está usando numpy, tiene disponible la función argsort ():
http://docs.scipy.org/doc/numpy/reference/generated/numpy.argsort.html
Esto devuelve los argumentos que ordenarían la matriz o la lista.
fuente
Algo así como el siguiente:
enumerate(myList)le da una lista que contiene tuplas de (índice, valor):Ordena la lista pasándola
sortedy especificando una función para extraer la clave de clasificación (el segundo elemento de cada tupla; para esolambdasirve. Finalmente, el índice original de cada elemento ordenado se extrae usando la[i[0] for i in ...]comprensión de la lista.fuente
itemgetter(1)lugar de la función lambdaitemgetterfunción en eloperatormódulo, FYI. Entonces hazlofrom operator import itemgetterpara usarlo.sorted_items, sorted_inds = zip(*sorted([(i,e) for i,e in enumerate(my_list)], key=itemgetter(1)))x = [3,1,2]; numpy.argsort(x)produce [1,2,0].fuente
Las respuestas con
enumerateson agradables, pero personalmente no me gusta la lambda utilizada para ordenar por el valor. Lo siguiente solo invierte el índice y el valor, y lo ordena. Por lo tanto, primero se ordenará por valor, luego por índice.fuente
Respuesta actualizada con
enumerateyitemgetter:Comprima las listas juntas: el primer elemento en la tupla será el índice, el segundo es el valor (luego ordénelo usando el segundo valor de la tupla
x[1], x es la tupla)O usando
itemgetterdesde eloperatormódulo`:fuente
Hice una comprobación rápida del rendimiento de estos con perfplot (un proyecto mío) y descubrí que es difícil recomendar algo más que numpy (tenga en cuenta la escala de registro):
Código para reproducir la trama:
fuente
Si no quieres usar numpy,
es más rápido, como se demuestra aquí .
fuente
Esencialmente necesitas hacer un
argsort, qué implementación necesita depende si desea usar bibliotecas externas (por ejemplo, NumPy) o si desea permanecer en Python puro sin dependencias.La pregunta que debe hacerse es: ¿quiere el
Desafortunadamente, el ejemplo en la pregunta no deja en claro lo que se desea porque ambos darán el mismo resultado:
Elegir el
argsortimplementaciónSi tiene NumPy a su disposición, simplemente puede usar la función
numpy.argsorto el métodonumpy.ndarray.argsort.Ya se mencionó una implementación sin NumPy en algunas otras respuestas, así que resumiré la solución más rápida de acuerdo con la respuesta de referencia aquí
Obteniendo los índices que ordenarían la matriz / lista
Para obtener los índices que ordenarían la matriz / lista, simplemente puede llamar
argsorta la matriz o lista. Estoy usando las versiones de NumPy aquí, pero la implementación de Python debería dar los mismos resultadosEl resultado contiene los índices necesarios para obtener la matriz ordenada.
Dado que la matriz ordenada sería
[1, 2, 3, 4]la matriz ordenada contiene los índices de estos elementos en el original.1y está en el índice1del original, por lo que el primer elemento del resultado es1.2está en el índice2en el original, por lo que el segundo elemento del resultado es2.3está en el índice0en el original, por lo que el tercer elemento del resultado es0.4y está en el índice3en el original, por lo que el último elemento del resultado es3.Obtener los índices que tendrían los elementos en la matriz / lista ordenada
En este caso, deberá aplicar
argsortdos veces :En este caso :
3, que es el tercer valor más grande, por lo que tendría un índice2en la matriz / lista ordenada, por lo que el primer elemento es2.1, que es el valor más pequeño, por lo que tendría un índice0en la matriz / lista ordenada para que el segundo elemento sea0.2, que es el segundo valor más pequeño, por lo que tendría un índice1en la matriz / lista ordenada para que el tercer elemento sea1.4cuál es el valor más grande, por lo que tendría un índice3en la matriz / lista ordenada, por lo que el último elemento es3.fuente
Las otras respuestas son incorrectas.
Ejecutar
argsortuna vez no es la solución. Por ejemplo, el siguiente código:rinde lo
array([1, 2, 0], dtype=int64)que no es lo que queremos.La respuesta debería ser correr
argsortdos veces:da
array([2, 0, 1], dtype=int64)como se esperaba.fuente
x[2](3) sea el elemento más pequeño yx[1](1) el elemento más grande (ya que la clasificación de enteros los ordena de menor a mayor valor). Además, con el ejemplo de OP, un solonp.argsort([1, 2, 3, 100, 5])rendimientoarray([0, 1, 2, 4, 3]), que parece ser el índice que quiere el OP.arr = [1,2,3,100, 5, 9] res = np.argsort(arr) print(res), obtenemos[0 1 2 4 5 3]cuál está mal.arr[res]rendimientosarray([ 1, 2, 3, 5, 9, 100]), que parecen estar perfectamente bien, ya que esa matriz resultante está en orden (creciente).arr=[1,2,3,100, 5, 9], espero que la salida seainds=[0,1,2,5,3,4], porque este es el orden en el que ordenará los elementos (cada vez más): 1 está en el lugar de 0, 2 en el primer lugar, ..., 5 en el 3er lugar y 9 en el 4to lugar. Para obtener esa salida (inds) necesito ejecutarargsortdos veces, como mencioné.sort, creo que el OP quiere la otra funcionalidad, comonp.argsortse usa normalmente (donde se puede usararr[np.argsort[arr]]para obtener la matriz ordenada, como en el último ejemplo de MATLAB). Su respuesta se aplica a este caso / pregunta en su lugar.Importar numpy como np
PARA ÍNDICE
argsort Devuelve los índices de S en orden ordenado
POR VALOR
fuente
Crearemos otra matriz de índices de 0 a n-1. Luego comprima esto en la matriz original y luego ordénelo según los valores originales.
``
fuente