2016-03-30 28 views
3

Bir N-boyutlu numpy dizisi x ve bir (N-1) boyutlu dizin dizisi m (örneğin, m = x.argmax(axis=-1)) olduğunu varsayalım. y[i_1, ..., i_N-1] = x[i_1, ..., i_N-1, m[i_1, ..., i_N-1]] (argmax örnek için y = x.max(axis=-1) eşdeğeri olacaktır) y (N-1) boyutlu dizi oluşturmak istiyorum. N için = 3 Ben keyfi N için bu, nasıl yapacağız benSayısal olarak indeksleme (max/argmax ile ilgili)

y = x[np.arange(x.shape[0])[:, np.newaxis], np.arange(x.shape[1]), m] 

sorudur tarafından istediğini elde edebiliriz?

shp = x.shape[:-1] 
n_ele = np.prod(shp) 
y_out = x.reshape(n_ele,-1)[np.arange(n_ele),m.ravel()].reshape(shp) 

en 6 dimensions bir ndarray ile örnek bir vaka ele alalım ve en son haline indeksine m = x.argmax(axis=-1) kullanıyor diyelim -

cevap

1

İşte keyfi boyutların çok boyutlu diziler işlemek için reshaping ve linear indexing kullanarak tek yaklaşım boyut. Yani, çıktı x.max(-1) olacaktır. önerdiği çözüm için bunu doğrulamak edelim -

In [121]: x = np.random.randint(0,9,(4,5,3,3,2,4)) 

In [122]: m = x.argmax(axis=-1) 

In [123]: shp = x.shape[:-1] 
    ...: n_ele = np.prod(shp) 
    ...: y_out = x.reshape(n_ele,-1)[np.arange(n_ele),m.ravel()].reshape(shp) 
    ...: 

In [124]: np.allclose(x.max(-1),y_out) 
Out[124]: True 

ben şıklığı için @B. M.'s solution sevdim.

def reshape_based(x,m): 
    shp = x.shape[:-1] 
    n_ele = np.prod(shp) 
    return x.reshape(n_ele,-1)[np.arange(n_ele),m.ravel()].reshape(shp) 

def indices_based(x,m): ## @B. M.'s solution 
    firstdims=np.indices(x.shape[:-1]) 
    ind=tuple(firstdims)+(m,) 
    return x[ind] 

Zamanlamaları - - Yani, burada kriter için bir çalışma zamanı testi bu iki var

In [152]: x = np.random.randint(0,9,(4,5,3,3,4,3,6,2,4,2,5)) 
    ...: m = x.argmax(axis=-1) 
    ...: 

In [153]: %timeit indices_based(x,m) 
10 loops, best of 3: 30.2 ms per loop 

In [154]: %timeit reshape_based(x,m) 
100 loops, best of 3: 5.14 ms per loop 
+0

Teşekkürler! Bu çalışıyor. Sadece son satır – BlindDriver

+0

@BlindDriver Evet '.reshape (shp)' eklemek istiyorum, bu bir yazım hatası oldu. – Divakar

2

sen indices kullanabilirsiniz:

firstdims=np.indices(x.shape[:-1]) 

Ve senin ekleyin:

ind=tuple(firstdims)+(m,) 

Sonra x[ind] istediğin şey.

In [228]: allclose(x.max(-1),x[ind]) 
Out[228]: True 
+0

Çok daha zarif! Bunu np.indices' yapmak? – Divakar

+0

Güzel! Bu endeksler işlevini bilmiyordum. – BlindDriver