Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: intersection indices numpy array

How can I get the indices of intersection points between two numpy arrays? I can get intersecting values with 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]) 

But how can I get the indices into a of the values in inter?

like image 689
invis Avatar asked Jul 14 '12 12:07

invis


People also ask

How do you find the intersection of two arrays in Numpy?

intersect1d() function find the intersection of two arrays and return the sorted, unique values that are in both of the input arrays. Parameters : arr1, arr2 : [array_like] Input arrays.


1 Answers

You could use the boolean array produced by in1d to index an arange. Reversing a so that the indices are different from the values:

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

intersect1d still returns the same values...

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

But in1d returns a boolean array:

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

Which can be used to index a range:

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

To simplify the above, though, you could use nonzero -- this is probably the most correct approach, because it returns a tuple of uniform lists of X, Y... coordinates:

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

Or, equivalently:

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

The result can be used as an index to arrays of the same shape as a with no problems.

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

But note that under many circumstances, it makes sense just to use the boolean array itself, rather than converting it into a set of non-boolean indices.

Finally, you can also pass the boolean array to argwhere, which produces a slightly differently-shaped result that's not as suitable for indexing, but might be useful for other purposes.

>>> numpy.argwhere(numpy.in1d(a, b)) array([[0],        [3],        [8]]) 
like image 65
senderle Avatar answered Sep 29 '22 22:09

senderle