2013-07-22 42 views
3

下面是一個小代碼來說明問題。numpy數組中值的位置的位置

A = array([[1,2], [1,0], [5,3]]) 
f_of_A = f(A) # this is precomputed and expensive 


values = array([[1,2], [1,0]]) 


# location of values in A 
# if I just had 1d values I could use numpy.in1d here 
indices = array([0, 1]) 


# example of operation type I need (recalculating f_of_A as needed is not an option) 
f_of_A[ indices ] 

所以,基本上我認爲我需要一些相當於in1d的更高維度。這樣的事情存在嗎?還是有其他方法?

看起來像還有一個searchsorted()函數,但似乎也適用於1d陣列。在這個例子中,我使用了2d點,但任何解決方案也需要爲3d點工作。

回答

2

好的,這就是我想出來的。

要找到一個多維指標的價值,讓我們說ii = np.array([1,2]),我們可以這樣做:

n.where((A == ii).all(axis=1))[0] 

讓我們打破這種下來,我們有A == ii,這將給逐元素的比較與ii每個排A。我們希望整行都是真實的,所以我們添加.all(axis=1)來摺疊它們。要找到這些指標發生的位置,我們將其插入np.where並獲取元組的第一個值。

現在,我還沒有一個快速的方法來做到這一點與多個指標(儘管我有一種感覺)。然而,這將完成這項工作:

np.hstack([np.where((A == values[i]).all(axis=1))[0] for i in xrange(len(values))]) 

這基本上只是調用上面,爲values每個值,並連接結果。

更新:

這裏是多維的情況下(全部一氣呵成,應該還算快):

np.where((np.expand_dims(A, -1) == values.T).all(axis=1).any(axis=1))[0] 
+0

你能解釋一下如何axis''作品?我正在閱讀'np.all',並不明白'axis'是什麼意思。 –

1

您可以使用np.in1d超過您最初的陣列的視圖所有座標坍塌成D型np.void的單一變量:

import numpy as np 

A = np.array([[1,2], [1,0], [5,3]]) 
values = np.array([[1,2], [1,0]]) 

# Make sure both arrays are contiguous and have common dtype 
common_dtype = np.common_type(A, values) 
a = np.ascontiguousarray(A, dtype=common_dtype) 
vals = np.ascontiguousarray(values, dtype=common_dtype) 

a_view = A.view((np.void, A.dtype.itemsize*A.shape[1])).ravel() 
values_view = values.view((np.void, 
          values.dtype.itemsize*values.shape[1])).ravel() 

現在每次電子郵件的a_viewvalues_view是一個點的座標,所以你可以做任何你會使用的1D魔法。我不知道如何使用np.in1d雖則發現指數,所以我會去的np.searchsorted路線:

sort_idx = np.argsort(a_view) 
locations = np.searchsorted(a_view, values_view, sorter=sort_idx) 
locations = sort_idx[locations] 

>>> locations 
array([0, 1], dtype=int64) 
+0

謝謝,我嘗試使用1d視圖,但我認爲我的問題不是使用np.ascontiguousarray()。至於np.in1d,這將生成一個掩碼而不是索引 – user1984528