Considérez le code suivant:
avgDists = np.array([1, 8, 6, 9, 4])
ids = avgDists.argsort()[:n]
Cela me donne des indices des n
plus petits éléments. Est-il possible d'utiliser la même chose argsort
dans l'ordre décroissant pour obtenir les indices des n
éléments les plus élevés?
ids = np.array(avgDists).argsort()[-n:]
?[3, 1, 2]
. Votre ligne produit[2, 1, 3]
(si n == 3 à titre d'exemple)ids = np.array(avgDists).argsort()[-n:][::-1]
. Le problème est d'éviter de faire une copie de la liste entière, ce que vous obtenez lorsque vous ajoutez un-
devant. Non pertinent pour le petit exemple du PO, pourrait l'être pour des cas plus importants.np.array(avgDists).argsort()[::-1][:n]
va le faire. De plus, si vous comptez utiliser numpy, restez dans numpy. Commencez par convertir la liste en tableau:avgDist=np.array(avgDists)
puis elle devientavgDist.argsort()[::-1][:n}
Réponses:
Si vous annulez un tableau, les éléments les plus bas deviennent les éléments les plus élevés et vice-versa. Par conséquent, les indices des
n
éléments les plus élevés sont:Une autre façon de raisonner à ce sujet, comme mentionné dans les commentaires , est d'observer que les gros éléments arrivent en dernier dans l'argsort. Ainsi, vous pouvez lire à partir de la queue de l'argument pour trouver les
n
éléments les plus élevés:Les deux méthodes sont O (n log n) en complexité temporelle, car l'
argsort
appel est ici le terme dominant. Mais la seconde approche a un bel avantage: elle remplace une négation O (n) du tableau par un O (1) tranche . Si vous travaillez avec de petits tableaux à l'intérieur de boucles, vous pouvez obtenir des gains de performances en évitant cette négation, et si vous travaillez avec d'énormes tableaux, vous pouvez économiser sur l'utilisation 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 mot-clékind='mergesort'
, alors la première stratégie préservera la stabilité du tri, mais la deuxième stratégie cassera la stabilité (c'est-à-dire les positions égales les éléments seront inversés).Exemple d'horaires:
En utilisant un petit tableau de 100 flotteurs et une longueur de 30 queue, la méthode de visualisation était environ 15% plus rapide
Pour les tableaux plus grands, le tri d'argument est dominant et il n'y a pas de différence de temps significative
Veuillez noter que le commentaire de nedim ci-dessous est incorrect. Le fait de tronquer avant ou après l'inversion ne fait aucune différence en termes d'efficacité, car ces deux opérations ne font que parcourir différemment une vue du tableau et ne copient pas réellement les données.
la source
np.array(avgDists).argsort()[:-n][::-1]
Tout comme Python, en cela
[::-1]
inverse le tableau retourné parargsort()
et[:n]
donne les n derniers éléments:L'avantage de cette méthode est qu'il
ids
s'agit d'une vue des avgDists:(Le 'OWNDATA' étant False indique qu'il s'agit d'une vue, pas d'une copie)
Une autre façon de faire est quelque chose comme:
Le problème est que la façon dont cela fonctionne est de créer un négatif de chaque élément du tableau:
ANd crée une copie pour ce faire:
Donc, si vous chronométrez chacun, avec ce très petit ensemble de données:
La méthode d'affichage est nettement plus rapide (et utilise 1/2 de la mémoire ...)
la source
Vous pouvez utiliser les commandes d'inversion
numpy.flipud()
ounumpy.fliplr()
pour obtenir les index dans l'ordre décroissant après le tri à l'aide de laargsort
commande. C'est ce que je fais habituellement.la source
Au lieu d'utiliser,
np.argsort
vous pouvez utilisernp.argpartition
- si vous n'avez besoin que des indices des n éléments les plus bas / les plus élevés.Cela ne nécessite pas de trier tout le tableau mais juste la partie dont vous avez besoin, mais notez que "l'ordre à l'intérieur de votre partition" n'est pas défini, donc bien qu'il donne les bons indices, ils peuvent ne pas être correctement ordonnés:
la source
Vous pouvez créer une copie du tableau, puis multiplier chaque élément par -1.
En conséquence, les éléments avant les plus grands deviendraient les plus petits.
Les indéces des n plus petits éléments de la copie sont les n plus grands éléments de l'original.
la source
-array
Avec votre exemple:
Obtenez des index de n valeurs maximales:
Triez-les par ordre décroissant:
Obtenez des résultats (pour n = 4):
la source
Comme @Kanmani l'a laissé entendre, une implémentation plus facile à interpréter peut être utilisée
numpy.flip
, comme dans l'exemple suivant:En utilisant le modèle de visiteur plutôt que les fonctions membres, il est plus facile de lire l'ordre des opérations.
la source
Une autre façon consiste à n'utiliser qu'un '-' dans l'argument pour argsort comme dans: "df [np.argsort (-df [:, 0])]", à condition que df soit le dataframe et que vous vouliez le trier par le premier colonne (représentée par le numéro de colonne «0»). Modifiez le nom de la colonne selon vos besoins. Bien entendu, la colonne doit être numérique.
la source