2016-10-23 9 views
1

Ich habe ein Array [2, 4, 2, 1, 3, 2, 2] und ich möchte Top-3-Wert-Indizes in absteigender Reihenfolge erhalten. Also sollte meine Ausgabe [1,4,0] sein, das sind die Indizes der obersten 3 Elemente des Arrays in absteigender Reihenfolge. (Ähnliche Artikelindizes werden toleriert). Ich benutze bottelneck, was teilweise meine Arbeit macht.Get Top-N-Elemente aus Array in absteigender Reihenfolge

import bottleneck 
import numpy as np 
a = np.array([2, 4, 2, 1, 3, 2, 2]) 
b = np.array(bottleneck.argpartsort(-a, 3)[:3]) 
print(b) 

die [4 1 5] die die korrekte obere 3 (n) Indizes des Arrays gibt, aber nicht in der absteigenden Reihenfolge. Gibt es eine eingebaute Funktion dieser Ausgabe einzustellen, um

Antwort

3

bieten absteigend können Sie np.argsort

import numpy as np 
a = np.array([2, 4, 2, 1, 3, 2, 2]) 
b = np.argsort(a)[-3:] 
b = b[::-1] 

verwenden Hinweis: Die letzten beiden Zeilen weiter vereinfacht werden kann (wenn auch mit nicht viel Rechenvorteil)

b = np.argsort(a)[-3:][::-1] 
# or, as juanpa suggested 
b = np.argsort(a)[-1:-4:-1] 

Alle gibt den folgenden Wert von b

array([1, 4, 6]) 
+2

Sie können in einem Schritt die Wende- und Slicing tun: 'np.array (np .argsort (a)) [- 1: -4: -1] ' –

+1

Aah schön. Danke für die Köpfe hoch! :-) –

0

Ich glaube, bottleneck.argpartsort tut etwas ähnlich wie np.argpartiton. Also, lass uns das benutzen. Jetzt, mit np.argpartiton anstelle von 3, müssen wir range(3) verwenden, um die sortierte Reihenfolge beizubehalten. Mit nur einem Skalar wird argpartiton diese 3 Elemente nicht sortieren, aber mit range(3) wird es.

Lasst uns hier ein Beispiel geben, dass zu präsentieren -

In [360]: a 
Out[360]: 
array([ 0.6082239 , 0.74932587, 0.50574681, 0.85241966, 0.91742228, 
     0.9984438 , 0.6876266 , 0.90651069, 0.53746683, 0.70674607]) 

In [361]: np.argpartition(-a,3) # 4,5,7 are the top 3, but not in sorted order 
Out[361]: array([4, 5, 7, 3, 1, 9, 6, 2, 8, 0]) 

In [362]: np.argpartition(-a,range(3)) # Sorted order maintained for top 3 
Out[362]: array([5, 4, 7, 3, 1, 0, 6, 2, 8, 9]) 

Zusätzlich mit np.argpartiton es werden die übrigen Elemente in dem Array nicht sortiert werden und somit Laufzeit Nutzen es bietet. Dies wäre von großem Vorteil, wenn wir versuchen würden, die obersten N Elemente in sortierter Reihenfolge zu erhalten, wobei N eine relativ kleinere Zahl als die Länge des Arrays ist.

So würden wir eine Implementierung mit np.argpartiton, wie so haben -

a[np.argpartition(-a,range(3))[:3]] 

Runtime Test -

In [342]: a = np.random.rand(10000) 

In [343]: %timeit a[np.argsort(a)[-1:-4:-1]] #@R. S. Nikhil Krishna's soln 
1000 loops, best of 3: 907 µs per loop 

In [344]: %timeit a[np.argpartition(-a,range(3))[:3]] 
10000 loops, best of 3: 67.9 µs per loop 
Verwandte Themen