2014-10-28 12 views
6

Erhalten eines Histogramms der Form 100x100x100 Anbetracht würde Ich mag die 2 höchsten Werte a und b finden, und ihre Indizes (a1, a2, a3) und (b1, b2, b3), wie zum Beispiel:die Indizes der N höchsten Werte in einem ndarray

hist[a1][a2][a3] = a 
hist[b1][b2][b3] = b 

können wir leicht den höchsten Wert mit hist.max(), aber wie können wir die X höchsten Werte in einem ndarray bekommen?

Ich verstehe, dass man in der Regel np.argmax verwendet die Wertindizes abrufen, aber in diesem Fall:

hist.argmax().shape =() # single value 
for i in range(3): 
    hist.argmax(i).shape = (100, 100) 

Wie kann ich eine Form (3), ein Tupel mit einem Wert pro Dimension bekommen?

Antwort

11

können Sie verwenden numpy.argpartition auf abgeflachte Version von Array zuerst die Indizes der oberen k Elemente zu erhalten, und dann können Sie diese 1D-Indizes umwandeln als je die Form des Array numpy.unravel_index mit:

>>> arr = np.arange(100*100*100).reshape(100, 100, 100) 
>>> np.random.shuffle(arr) 
>>> indices = np.argpartition(arr.flatten(), -2)[-2:] 
>>> np.vstack(np.unravel_index(indices, arr.shape)).T 
array([[97, 99, 98], 
     [97, 99, 99]]) 
) 
>>> arr[97][99][98] 
999998 
>>> arr[97][99][99] 
999999 
+0

Danke, ich konnte nicht herausfinden, wie man richtig nutzen argpartition und unravel_index, jetzt macht durchaus Sinn: Indizes der N größten Sets Sie die nlargest Funktion aus dem heapq Modul nutzen könnten. Akzeptiert Ihre Antwort, aber wenn @ atomh33ls seine Antwort aktualisiert, werde ich die 2 Lösungen Benchmarks :) – Fandekasp

+1

[Benchmark-Test] (https://gist.github.com/Fandekasp/20d428684a65b32d7c02): Argpartition ist schnell :) – Fandekasp

0

Ich nehme an können Sie Dazu:

(Pseudo-Code)

#work on a copy 
working_hist = copy(hist) 
greatest = [] 

min_value = hist.argmin().shape 

#while searching for the N greatest values, do N times 
for i in range(N): 
    #get the current max value 
    max_value = hist.argmax().shape 
    #save it 
    greatest.append(max_value) 
    #and then replace it by the minimum value 
    hist(max_value.shape)= min_value 

ich habe seit Jahren nicht mehr verwendet numpy, also bin ich nicht sicher von der Syntax. Der Code ist nur hier, um Ihnen eine Pseudo-Code-ähnliche Antwort zu geben.

Wenn Sie behalten auch die Position des Wertes Sie Sie extrahieren vermeiden auf einer Kopie des Artikels zu arbeiten, indem sie die extrahierten Informationen mit Hilfe der Matrix am Ende wieder herzustellen.

2

könnten Sie where verwenden:

a=np.random.random((100,100,100)) 
np.where(a==a.max()) 
(array([46]), array([62]), array([61])) 

in einem einzelnen Array zu erhalten:

np.hstack(np.where(a==a.max())) 
array([46, 62, 61]) 

und, wie die OP für ein Tupel gestellt:

tuple(np.hstack(np.where(a==a.max()))) 
(46, 62, 61) 

EDIT:

Um die

N=3 
np.where(a>=heapq.nlargest(3,a.flatten())[-1]) 
(array([46, 62, 61]), array([95, 85, 97]), array([70, 35, 2])) 
+3

Vielen Dank! Ich schrieb einen [Benchmark-Test] (https://gist.github.com/Fandekasp/20d428684a65b32d7c02), die zeigt, dass die argpartition Methode 22-mal schneller ist als dort, wo. Danke, dass du dieses Beispiel geliefert hast, habe viel daraus gelernt! – Fandekasp

Verwandte Themen