Considere el siguiente código:
avgDists = np.array([1, 8, 6, 9, 4])
ids = avgDists.argsort()[:n]
Esto me da índices de los n
elementos más pequeños. ¿Es posible usar esto argsort
en orden descendente para obtener los índices de los n
elementos más altos?
ids = np.array(avgDists).argsort()[-n:]
?[3, 1, 2]
. Su línea produce[2, 1, 3]
(si n == 3 como ejemplo)ids = np.array(avgDists).argsort()[-n:][::-1]
. La cuestión es evitar hacer una copia de toda la lista, que es lo que obtienes cuando agregas un-
frente. No relevante para el pequeño ejemplo del OP, podría ser para casos más grandes.np.array(avgDists).argsort()[::-1][:n]
lo hará. Además, si vas a usar numpy, quédate en numpy. Primero convierta la lista a una matriz:avgDist=np.array(avgDists)
luego se convierteavgDist.argsort()[::-1][:n}
Respuestas:
Si niega una matriz, los elementos más bajos se convierten en los elementos más altos y viceversa. Por lo tanto, los índices de los
n
elementos más altos son:Otra forma de razonar sobre esto, como se menciona en los comentarios , es observar que los grandes elementos son los últimos en la clasificación. Entonces, puedes leer desde la cola del argsort para encontrar los
n
elementos más altos:Ambos métodos son O (n log n) en complejidad temporal, porque la
argsort
llamada es el término dominante aquí. Pero el segundo enfoque tiene una buena ventaja: reemplaza una negación O (n) de la matriz con un segmento O (1) . Si está trabajando con matrices pequeñas dentro de bucles, entonces puede obtener algunas mejoras de rendimiento al evitar esa negación, y si está trabajando con matrices enormes, puede ahorrar en el uso de memoria porque la negación crea una copia de toda la matriz.Tenga en cuenta que estos métodos no siempre dan resultados equivalentes: si se solicita una implementación de clasificación estable
argsort
, por ejemplo, pasando el argumento de la palabra clavekind='mergesort'
, entonces la primera estrategia preservará la estabilidad de clasificación, pero la segunda estrategia romperá la estabilidad (es decir, las posiciones de igual los artículos serán revertidos).Tiempos de ejemplo:
Usando una pequeña matriz de 100 flotadores y una longitud de 30 colas, el método de visualización fue aproximadamente un 15% más rápido
Para matrices más grandes, el argsort es dominante y no hay una diferencia de tiempo significativa
Tenga en cuenta que el comentario de nedim a continuación es incorrecto. Si se debe truncar antes o después de la inversión, no hay diferencia en la eficiencia, ya que ambas operaciones solo muestran una vista de la matriz de manera diferente y en realidad no copian datos.
fuente
np.array(avgDists).argsort()[:-n][::-1]
Al igual que Python, en eso
[::-1]
invierte la matriz devuelta porargsort()
y[:n]
da los últimos n elementos:La ventaja de este método es que
ids
es una vista de avgDists:(El 'OWNDATA' es Falso indica que esta es una vista, no una copia)
Otra forma de hacer esto es algo como:
El problema es que la forma en que esto funciona es crear negativos de cada elemento en la matriz:
ANd crea una copia para hacerlo:
Entonces, si cronometra cada uno, con este conjunto de datos muy pequeño:
El método de visualización es sustancialmente más rápido (y usa la mitad de la memoria ...)
fuente
Puede usar los comandos flip
numpy.flipud()
onumpy.fliplr()
para obtener los índices en orden descendente después de ordenarlos con elargsort
comando. Eso es lo que suelo hacer.fuente
En lugar de usar
np.argsort
, podría usarnp.argpartition
, si solo necesita los índices de los n elementos más bajos / más altos.Eso no requiere ordenar toda la matriz, sino solo la parte que necesita, pero tenga en cuenta que el "orden dentro de su partición" no está definido, por lo que si bien proporciona los índices correctos, es posible que no estén ordenados correctamente:
fuente
Puede crear una copia de la matriz y luego multiplicar cada elemento con -1.
Como efecto, los elementos más grandes anteriores se convertirían en los más pequeños.
Las indecesiones de los n elementos más pequeños en la copia son los n elementos más grandes en el original.
fuente
-array
Como insinuó @Kanmani, se puede usar una implementación más fácil de interpretar
numpy.flip
, como se muestra a continuación:Al usar el patrón de visitante en lugar de las funciones de miembro, es más fácil leer el orden de las operaciones.
fuente
Con tu ejemplo:
Obtenga índices de n valores máximos:
Clasifíquelos en orden descendente:
Obtenga resultados (para n = 4):
fuente
Otra forma es usar solo un '-' en el argumento para argsort como en: "df [np.argsort (-df [:, 0])]", siempre que df sea el marco de datos y desee ordenarlo por el primero columna (representada por el número de columna '0'). Cambie el nombre de la columna según corresponda. Por supuesto, la columna tiene que ser numérica.
fuente