web-dev-qa-db-fra.com

J'ai besoin des N valeurs minimales (index) dans un tableau numpy

Salut, j'ai un tableau avec X quantité de valeurs, je voudrais localiser les index des dix plus petites valeurs. Dans ce lien, ils ont calculé le maximum efficacement, Comment obtenir des indices de N valeurs maximales dans un tableau numpy? mais je ne peux pas encore commenter les liens, donc je dois republier la question.

Je ne sais pas quels indices je dois changer pour atteindre les valeurs minimales et non maximales. C'est leur code

In [1]: import numpy as np

In [2]: arr = np.array([1, 3, 2, 4, 5])

In [3]: arr.argsort()[-3:][::-1]
Out[3]: array([4, 3, 1]) 
21
astrochris

Si vous appelez

arr.argsort()[:3]

Il vous donnera les indices des 3 plus petits éléments.

array([0, 2, 1], dtype=int64)

Donc, pour n, vous devez appeler

arr.argsort()[:n]
38
petrichor

Depuis que cette question a été publiée, numpy a été mis à jour pour inclure un moyen plus rapide de sélectionner les plus petits éléments d'un tableau en utilisant argpartition . Il a d'abord été inclus dans Numpy 1.8.

En utilisant la réponse de Snarly comme source d'inspiration, nous pouvons rapidement trouver le k=3 les plus petits éléments:

In [1]: import numpy as np

In [2]: arr = np.array([1, 3, 2, 4, 5])

In [3]: k = 3

In [4]: ind = np.argpartition(arr, k)[:k]

In [5]: ind
Out[5]: array([0, 2, 1])

In [6]: arr[ind]
Out[6]: array([1, 2, 3])

Cela s'exécutera dans O(n) fois car il n'a pas besoin de faire un tri complet. Si vous avez besoin que vos réponses soient triées ( Remarque: dans ce cas le tableau de sortie était trié mais ce n'est pas garanti), vous pouvez trier la sortie:

In [7]: sorted(arr[ind])
Out[7]: array([1, 2, 3])

Cela fonctionne sur O (n + k log k) car le tri a lieu sur la liste de sortie plus petite.

20
Alex

Je ne garantis pas que ce sera plus rapide, mais un meilleur algorithme s'appuiera sur heapq.

import heapq
indices = heapq.nsmallest(10,np.nditer(arr),key=arr.__getitem__)

Cela devrait fonctionner dans environ O(N) opérations alors que l'utilisation de argsort nécessiterait O(NlogN) opérations. Cependant, l'autre est poussé dans un C hautement optimisé, il pourrait donc toujours mieux fonctionner. Pour être sûr, vous devez exécuter des tests sur vos données réelles.

6
mgilson

N'inversez simplement pas les résultats du tri.

In [164]: a = numpy.random.random(20)

In [165]: a
Out[165]: 
array([ 0.63261763,  0.01718228,  0.42679479,  0.04449562,  0.19160089,
        0.29653725,  0.93946388,  0.39915215,  0.56751034,  0.33210873,
        0.17521395,  0.49573607,  0.84587652,  0.73638224,  0.36303797,
        0.2150837 ,  0.51665416,  0.47111993,  0.79984964,  0.89231776])

Trié:

In [166]: a.argsort()
Out[166]: 
array([ 1,  3, 10,  4, 15,  5,  9, 14,  7,  2, 17, 11, 16,  8,  0, 13, 18,
       12, 19,  6])

Dix premiers:

In [168]: a.argsort()[:10]
Out[168]: array([ 1,  3, 10,  4, 15,  5,  9, 14,  7,  2])
2
Mike Müller

Ce code enregistre 20 index de l'élément maximum de split_list dans Twenty_Maximum:

Twenty_Maximum = split_list.argsort()[-20:]

contre ce code enregistrer 20 index de l'élément minimum de split_list dans Twenty_Minimum:

Twenty_Minimum = split_list.argsort()[:20]
0
mohammadali68