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:
(-avgDists).argsort()[:n]
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:
avgDists.argsort()[::-1][:n]
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 clave kind='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
>>> avgDists = np.random.rand(100)
>>> n = 30
>>> timeit (-avgDists).argsort()[:n]
1.93 µs ± 6.68 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
>>> timeit avgDists.argsort()[::-1][:n]
1.64 µs ± 3.39 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
>>> timeit avgDists.argsort()[-n:][::-1]
1.64 µs ± 3.66 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Para matrices más grandes, el argsort es dominante y no hay una diferencia de tiempo significativa
>>> avgDists = np.random.rand(1000)
>>> n = 300
>>> timeit (-avgDists).argsort()[:n]
21.9 µs ± 51.2 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
>>> timeit avgDists.argsort()[::-1][:n]
21.7 µs ± 33.3 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
>>> timeit avgDists.argsort()[-n:][::-1]
21.9 µs ± 37.1 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
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.
ids = np.array(avgDists).argsort()[-n:]
?