42

如何获取两个 numpy 数组之间的交点索引?我可以得到相交的值intersect1d

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

但是我怎样才能将索引放入a中的值inter

4

4 回答 4

45

您可以使用生成的布尔数组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]])
于 2012-07-14T12:59:00.947 回答
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]
于 2016-09-20T21:47:46.527 回答
2
indices = np.argwhere(np.in1d(a,b))
于 2019-04-23T10:00:21.567 回答
1

对于Python >= 3.5,还有另一种解决方案

其他解决方案

让我们一步一步来。

基于问题的原始代码

import numpy as np

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

首先,我们创建一个带有零的 numpy 数组

c = np.zeros(len(a))
print (c)

输出

>>> [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]

其次,使用相交索引更改 c 的数组值。因此,我们有

c[inter] = 1
print (c)

输出

>>>[ 0.  0.  1.  0.  0.  0.  0.  1.  0.  0.  1.]

最后一步,使用 的特性np.nonzero(),它会准确地返回你想要的非零项的索引。

inter_with_idx = np.nonzero(c)
print (inter_with_idx)

最终输出

array([ 2, 7, 10])

参考

[1] numpy .非零

于 2018-01-17T09:30:19.557 回答