Python:交集索引numpy数组

时间:2012-07-14 12:47:04

标签: python arrays numpy

如何获得两个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 个答案:

答案 0 :(得分:37)

您可以使用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]])

答案 1 :(得分: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]

答案 2 :(得分:0)

对于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.nonzero

答案 3 :(得分:0)

indices = np.argwhere(np.in1d(a,b))