2014-10-28 13 views
6

Şekil 100x100x100 bir histogram göz önüne alındığında, a ve b en yüksek 2 değerini ve bunların endekslerini (a1, a2, a3) ve (b1, b2, b3) bulmak istiyorum), örneğin:Bir ndarray'da N en yüksek değerlerin indekslerini alın

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

Biz kolayca hist.max() ile en yüksek değeri elde edebilirsiniz, ama nasıl bir ndarray X en yüksek değerler elde edebilirsiniz?

Bir normalde değer endekslerini almak için np.argmax kullandığı anlıyoruz, ancak bu durumda:

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

nasıl bir şekil alabilir (3), boyut başına bir değere sahip bir tanımlama grubu? numpy.unravel_index kullanarak dizinin şekline göre

cevap

11

Önce üst k öğelerin endekslerini almak için dizinin düzleştirilmiş sürümüne numpy.argpartition kullanabilir ve daha sonra o 1D endeks dönüştürebilirsiniz:

>>> 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

sayesinde düzgün argpartition ve unravel_index nasıl kullanılacağını çözemedim, şimdi çok mantıklı. Cevabınızı kabul ettiniz, ancak @ atomh33ls cevabını güncellediyse, 2 çözümü kıyaslayacağım :) – Fandekasp

+1

[Benchmark testi] (https://gist.github.com/Fandekasp/20d428684a65b32d7c02): arg partition hızlıdır :) – Fandekasp

0

ben yapabilirsiniz varsayalım bunu yapmak:

(yalancı kod)

#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 

yıllardır numpy kullanmadıysanız, bu yüzden değilim sözdizimi kesin. Kod sadece size sözde kod gibi cevap vermek için geldi.

Ayıkladığınız değerin konumunu da korursanız, sonunda matrisini geri yüklemek için ayıklanan bilgileri kullanarak öğenin bir kopyasında çalışmayı engelleyebilirsiniz.

2

Sen where kullanabilirsiniz:

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

DÜZENLEME:

OP bir tuplea istedi olarak,

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

ve:

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

tek dizide almak

Almak için N büyük setleri endeksleri Eğer heapq modülünden nlargest işlevini kullanabilirsiniz:

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

Teşekkürler! Argpartisyon yönteminin 22 kat daha hızlı olduğunu gösteren bir [benchmark testi] (https://gist.github.com/Fandekasp/20d428684a65b32d7c02) yazdım. Bu örnek için teşekkür ederiz, ondan çok şey öğrendim! – Fandekasp

İlgili konular