Python:交集索引numpy数组

inv*_*vis 36 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])
Run Code Online (Sandbox Code Playgroud)

但是如何才能获得a值的索引inter呢?

sen*_*rle 42

您可以使用生成的布尔数组in1d来索引arange.反转a,使指数与值不同:

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

intersect1d 仍然返回相同的值...

>>> numpy.intersect1d(a, b)
array([ 2,  7, 10])
Run Code Online (Sandbox Code Playgroud)

但是in1d返回一个布尔数组:

>>> numpy.in1d(a, b)
array([ True, False, False,  True, False, False, False, False,  True,
       False, False], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

哪个可用于索引范围:

>>> 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])
Run Code Online (Sandbox Code Playgroud)

为了简化以上,不过,你可以使用nonzero-这可能是最正确的做法,因为它返回的统一名单的元组X,Y...坐标:

>>> numpy.nonzero(numpy.in1d(a, b))
(array([0, 3, 8]),)
Run Code Online (Sandbox Code Playgroud)

或者,等效地:

>>> numpy.in1d(a, b).nonzero()
(array([0, 3, 8]),)
Run Code Online (Sandbox Code Playgroud)

结果可以用作相同形状的数组的索引a,没有问题.

>>> a[numpy.nonzero(numpy.in1d(a, b))]
array([10,  7,  2])
Run Code Online (Sandbox Code Playgroud)

但请注意,在许多情况下,仅使用布尔数组本身是有意义的,而不是将其转换为一组非布尔索引.

最后,您还可以将布尔数组传递给argwhere,这会产生稍微不同形状的结果,这种结果不适合索引,但可能对其他用途有用.

>>> numpy.argwhere(numpy.in1d(a, b))
array([[0],
       [3],
       [8]])
Run Code Online (Sandbox Code Playgroud)

  • 如此粗糙,但它在Octave中更容易:) [inter indexA indexB] = intersect(A,b) (2认同)