Un moyen rapide pour trouver le plus grand de N éléments dans un tableau numpy
Je sais que je peux le faire comme suit:
import numpy as np
N=10
a=np.arange(1,100,1)
np.argsort()[-N:]
Cependant, il est très lent car il fait un plein de tri.
Je me demande si numpy fournir certaines méthodes de le faire vite.
- Double Possible de Comment obtenir des indices de N valeurs maximales dans un tableau numpy?
Vous devez vous connecter pour publier un commentaire.
La
goulot d'étranglement
module a un jeûne partiel méthode de tri qui fonctionne directement avec les tableaux Numpy:goulot d'étranglement.partition()
.Noter que
bottleneck.partition()
retourne les valeurs réelles triés, si vous voulez que l'index de la triés valeurs (ce quinumpy.argsort()
retourne), vous devez utilisergoulot d'étranglement.argpartition()
.J'ai comparé:
z = -bottleneck.partition(-a, 10)[:10]
z = a.argsort()[-10:]
z = heapq.nlargest(10, a)
où
a
aléatoire de 1 000 000-élément de tableau.Les horaires ont été comme suit:
bottleneck.partition()
: 25.6 ms par bouclenp.argsort()
: 198 ms par boucleheapq.nlargest()
: 358 ms par bouclenanargmax()
fait quelque chose d'assez différent de ce que l'OP est de demander. Je vais revenir à la modifier. Corrigez-moi si je me manque quelque chose.bottleneck
ajouté à l'EPD.nargmax
, pasnanargmax
.bottleneck.partsort()
etnp.argsort()
sont deux des choses légèrement différentes. Elles retournent une valeur et un index respectivement. Si vous souhaitez un goulot d'étranglement pour le retour de l'index, utilisezbottleneck.argpartsort
heapq.nlargest
n'est pas tout à fait juste. Il serait préférable d'exécuterheapq.nlargest(10, a.tolist())
numpy 1.8
implémentepartition
etargpartition
qui effectuent partielle de tri ( en O(n) fois, par opposition à une sorte qui est O(n) * log(n)).Résultat:
Calendrier:
[9, 8, 6, 7]
il est clair que n plus de vals ne sont pas dans l'ordre.argpartition
? Ne devrait-elle pas être fondamentalement la même, mais avec la sélection surtemp[:5]
au lieu detemp[4:]
alors? Ou alors j'ai loupé un détail crucial ici?-test
?np.partition
trier dans l'ordre croissant par défaut. Pour trier dans l'ordre décroissant, nous pouvons nous tourner tous les nombres négatifs (array([-9, -1, -3, -4, -8, -7, -2, -5, -6, 0])
) et de tri dans ce tableau à la place.Chaque signe négatif dans le projet de goulot d'étranglement solution
fait une copie des données. Nous pouvons supprimer les copies en faisant
Également le projet de numpy solution
rendements des indices et non des valeurs. La solution est d'utiliser des indices pour trouver les valeurs:
La vitesse relative des deux goulot d'étranglement des solutions dépend de l'ordre des éléments dans la table initiale, parce que les deux approches de partitionner les données en différents points.
En d'autres termes, le calendrier avec un ensemble aléatoire peut prendre soit la méthode look plus rapide.
La moyenne de la synchronisation à travers 100 random matrices, chacune avec 1 000 000 d'éléments, donne
cas où le moment où le code est comme suit:
J'ai eu ce problème et, depuis que cette question est de 5 ans, j'ai dû refaire tous les indices de référence et de modifier la syntaxe de goulot d'étranglement (il n'y a pas de
partsort
plus, c'estpartition
maintenant).J'ai utilisé les mêmes arguments que kwgoodman, sauf le nombre d'éléments récupérés, dont j'ai augmenté à 50 (pour mieux l'adapter à ma situation particulière).
J'ai obtenu ces résultats:
Donc, bottleneck_2 et numpy_2 (adas de la solution) étaient attachés.
Mais, à l'aide de
np.percentile
(numpy_2) vous avez ces topN éléments déjà triés, ce qui n'est pas le cas pour les autres solutions. D'autre part, si vous êtes également intéressé à l'index de ces éléments, centile n'est pas utile.J'ai ajouté les pandas trop, qui utilise goulot d'étranglement en dessous, si disponible (http://pandas.pydata.org/pandas-docs/stable/install.html#recommended-dependencies). Si vous avez déjà une pandas Série ou DataFrame pour commencer, vous êtes en de bonnes mains, il suffit d'utiliser
nlargest
et vous avez terminé.Le code utilisé pour l'indice de référence est comme suit (python 3, s'il vous plaît):
Peut-être
heapq.nlargest
Résultat:
Si vous voulez trouver les indices de la
n
plus grands éléments à l'aide debottleneck
vous pouvez utiliserbottleneck.argpartsort
Vous pouvez également utiliser numpy du percentile de la fonction. Dans mon cas, il était légèrement plus rapide goulot d'étranglement.partsort():
Temps moyen par boucle:
interpolation='nearest'
à l'appel ànp.percentile
. Voir documentation pour plus de détails.Si le stockage de la matrice comme une liste de numéros n'est pas problématique, vous pouvez utiliser
pour obtenir le
N
plus importants membres.