Si vous niez un tableau, les éléments les plus bas deviennent les éléments les plus hauts et vice-versa. Par conséquent, les indices du tableau n
les éléments les plus élevés sont :
(-avgDists).argsort()[:n]
Une autre façon de raisonner à ce sujet, comme mentionné dans le document commentaires c'est d'observer que les grands éléments viennent dernier dans la liste d'arguments. Ainsi, vous pouvez lire la queue de l'argsort pour trouver l'élément n
les éléments les plus élevés :
avgDists.argsort()[::-1][:n]
Les deux méthodes sont O(n log n) en termes de complexité temporelle, car le argsort
L'appel est le terme dominant ici. Mais la deuxième approche présente un avantage appréciable : elle remplace un O(n) négation du tableau avec un O(1) tranche. Si vous travaillez avec de petits tableaux à l'intérieur de boucles, vous pouvez obtenir des gains de performance en évitant cette négation, et si vous travaillez avec d'énormes tableaux, vous pouvez économiser de la mémoire car la négation crée une copie de l'ensemble du tableau.
Notez que ces méthodes ne donnent pas toujours des résultats équivalents : si une implémentation de tri stable est demandée à argsort
par exemple en passant l'argument du mot-clé kind='mergesort'
alors la première stratégie préservera la stabilité du tri, mais la seconde rompra la stabilité (c'est-à-dire que les positions des éléments égaux seront inversées).
Exemples d'horaires :
En utilisant un petit tableau de 100 flottants et une queue de longueur 30, la méthode de visualisation était environ 15% plus rapide.
>>> 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)
Pour les tableaux plus grands, l'argsort est dominant et il n'y a pas de différence de temps significative.
>>> 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)
Veuillez noter que le commentaire de nedim ci-dessous est incorrecte. Le fait de tronquer avant ou après l'inversion ne fait aucune différence en termes d'efficacité, puisque ces deux opérations ne font que déplacer une vue du tableau de manière différente et ne copient pas réellement les données.