2012-07-14 250 views
27

如何獲得兩個numpy數組之間的交叉點索引?我可以intersect1d得到相交值:Python:交叉索引numpy數組

import numpy as np 

a = np.array(xrange(11)) 
b = np.array([2, 7, 10]) 
inter = np.intersect1d(a, b) 
# inter == array([ 2, 7, 10]) 

但我怎麼能拿到指標進入價值ainter

回答

31

您可以使用in1d生成的布爾數組索引arange。倒車a從而使指數是不同的值:

>>> a[::-1] 
array([10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]) 
>>> a = a[::-1] 

intersect1d仍返回相同的值...

>>> numpy.intersect1d(a, b) 
array([ 2, 7, 10]) 

in1d返回一個布爾值數組:

>>> numpy.in1d(a, b) 
array([ True, False, False, True, False, False, False, False, True, 
     False, False], dtype=bool) 

哪可用於對一個範圍進行索引:

>>> numpy.arange(a.shape[0])[numpy.in1d(a, b)] 
array([0, 3, 8]) 
>>> indices = numpy.arange(a.shape[0])[numpy.in1d(a, b)] 
>>> a[indices] 
array([10, 7, 2]) 

爲了簡化以上,不過,你可以使用nonzero - 這可能是最正確的做法,因爲它返回的XY統一列表的元組...座標:

>>> numpy.nonzero(numpy.in1d(a, b)) 
(array([0, 3, 8]),) 

或者等價地:

>>> numpy.in1d(a, b).nonzero() 
(array([0, 3, 8]),) 

結果可以用作索引,以相同的形狀a,沒有任何問題的陣列。

>>> a[numpy.nonzero(numpy.in1d(a, b))] 
array([10, 7, 2]) 

但請注意,在很多情況下,它是有道理的只是使用布爾數組本身,而不是將其轉換爲一組非布爾指數。

最後,您還可以將布爾數組傳遞給argwhere,這會產生稍微不同的結果,但不適合索引,但可能對其他用途有用。

>>> numpy.argwhere(numpy.in1d(a, b)) 
array([[0], 
     [3], 
     [8]]) 
+2

那麼粗糙,但它的工作原理:) 更容易在八度: [除指數A indexB] =相交(A,B) – invis 2012-07-14 13:15:49

+0

謝謝你很多關於你的答案 ! in1d和intersect1d的 – invis 2012-07-14 18:32:48

+0

不一樣。 intersect1d給出了唯一的值,in1d給出了所有的交集,所以這個答案不會一直工作。 – Rik 2016-09-20 02:50:35

2

如果你需要得到唯一值由intersect1d給出:

import numpy as np 

a = np.array([range(11,21), range(11,21)]).reshape(20) 
b = np.array([12, 17, 20]) 
print(np.intersect1d(a,b)) 
#unique values 

inter = np.in1d(a, b) 
print(a[inter]) 
#you can see these values are not unique 

indices=np.array(range(len(a)))[inter] 
#These are the non-unique indices 

_,unique=np.unique(a[inter], return_index=True) 

uniqueIndices=indices[unique] 
#this grabs the unique indices 

print(uniqueIndices) 
print(a[uniqueIndices]) 
#now they are unique as you would get from np.intersect1d() 

輸出:

[12 17 20] 
[12 17 20 12 17 20] 
[1 6 9] 
[12 17 20] 
0

讓我們通過這一步一步來。

其他解決方案

首先,我們創建帶零點的numpy的陣列c中使用交叉索引

c[inter] = 1 
print c 
>>>[ 0. 0. 1. 0. 0. 0. 0. 1. 0. 0. 1.] 

的最後一步,使用特性

c = np.zeros(len(a)) 
print c 
>>> [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] 

其次,改變數組值它將返回索引的非零項

inter_with_idx = np.nonzero(c) 
print inter_with_idx 
>>>array([ 2, 7, 10]) 

參考

[1] numpy.nonzero