2015-09-25 101 views
3

當NumPy的使用切片,你會得到所有成對元素的索引列表,例如所有成對元素:使用索引這種行爲似乎並沒有列表/元組時NumPy的索引 -

>> im = np.arange(1,37).reshape((6, 6)) 
>> im[1:6:2,1:6:2] 
array([[ 8, 10, 12], 
     [20, 22, 34], 
     [32, 34, 36]]) 

然而被遵循:

>> im[(1,3,5),(1,3,5)] 
array([ 8, 22, 36]) 

>> im[[1,3,5],[1,3,5]] 
array([ 8, 22, 36]) 

它只是取得對角線(在這種情況下)。如果您不能將索引指定爲切片,例如(1,3,4)(1,3,6),則這是有問題的。對於這兩個元組,我期望得到的所有元素都可以在(1,1) (1,3) (1,6) (3,1) ...

我想到的所有解決方法都包括充實每一對元素,這些元素在嘗試從大量圖像中提取大量元素時非常昂貴。在MATLAB中,im([1,3,5],[1,3,5])做我想要的。我知道NumPy的索引中有很多技巧,我可能只是錯過了一些微妙之處。

作爲結論,例如變通方法:

im[np.meshgrid([1,3,5], [1,3,5], indexing='ij')] 
im[zip(*itertools.product([1,3,5], [1,3,5]))].reshape((3,3)) 
+1

你是對的,我原本在產生轉置的重塑命令中有'order ='F'。 – coderforlife

回答

3

嘗試numpy.ix_

>>> im[np.ix_((1,3,5),(1,3,5))] 
array([[ 8, 10, 12], 
    [20, 22, 24], 
    [32, 34, 36]]) 

或者你也可以直接做到這一點:

>>> ix = np.array([1, 3, 5]) 
>>> iy = np.array([1, 3, 5]) 
>>> im[ix[:, np.newaxis], iy[np.newaxis, :]] 
array([[ 8, 10, 12], 
     [20, 22, 24], 
     [32, 34, 36]]) 
+0

啊,所以如果指標是列或行向量這個工程。這看起來是最有希望的。 – coderforlife

+0

使用第二個示例對此進行了測試,結果非常好。我使用了第二個,因爲這些索引已經是列向量,所以它看起來像'im [ix,iy.T]'。這很乾淨,可能非常高效! – coderforlife

1

這是你需要什麼?

i1 = [1,3,5] 
i2 = [1,3,5] 
print im[i1][:,i2].ravel() 

注意在第一次建立索引時會創建一個臨時數組。如果你的陣列非常大,這可能是不可取的。

+2

這確實有效(如果你刪除'ravel')。但是,在那裏創建的臨時數據可能比使用'meshgrid'創建的臨時數據大(如果少於一半的列被創建)。但這是一個好方法。 – coderforlife

1

答案由其他人是正確的。只是爲了解釋爲什麼發生這種情況。

Indexing on numpy arrays文檔 -

當索引等 - x[obj] - 高級索引被觸發時選擇對象obj是非元組序列對象,ndarray(數據類型整數或布爾的) ,或一個至少包含一個序列對象或ndarray(數據類型爲integer或bool)的元組。

您的情況屬於第二,因此im[(1,3,5),(1,3,5)]觸發高級索引。並且稍後在documentation of Advanced indexing,解釋 -

高級索引始終是broadcast和迭代爲一體:

result[i_1, ..., i_M] == x[ind_1[i_1, ..., i_M], ind_2[i_1, ..., i_M], 
         ..., ind_N[i_1, ..., i_M]] 

注意,結果形狀是相同的(廣播)的索引陣列形狀ind_1 ,...,ind_N。

那它result[i_1]會 - x[ind_1[i_1],ind_2[i_1],...ind_N[i_1]]

文檔建議使用np.ix_實現類似於基本切片行爲 -

要實現類似上述的基本切片,廣播能行爲使用。功能ix_可以幫助這個廣播。以一個例子來最好地理解這一點。