Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine arguments where two numpy arrays intersect in Python

I have two arrays, say:

a, b = np.array([13., 14., 15., 32., 33.]), np.array([15., 16., 17., 33., 34., 47.])

I need to find the indices of all the elements in a that are not present in b. In the above example the result would be:

[0, 1, 3]

Because a[0], a[1] and a[3] are 13., 14. and 32., which are not present in b. Notice that I don't care to know the actual values of 13., 14. and 32. (I could have used set(a).difference(set(b)), in that case). I am genuinely interested in the indices only.

If possible the answer should be "vectorized", i.e. not using a for loop.

like image 934
astabada Avatar asked Aug 28 '13 10:08

astabada


People also ask

How do you find the intersection of two NumPy arrays in Python?

Step 1: Import numpy. Step 2: Define two numpy arrays. Step 3: Find intersection between the arrays using the numpy. intersect1d() function.

How do you check if two NumPy arrays are the same?

Method 1: We generally use the == operator to compare two NumPy arrays to generate a new array object. Call ndarray. all() with the new array object as ndarray to return True if the two NumPy arrays are equivalent.

How do you print the intersection of two arrays in Python?

To find the intersection of between two arrays, use the bitwise and (&) between the sets of given arrays and assign it into a variable Y in the form of lists. Print variable X and Y which is our required output.


3 Answers

You could use np.in1d:

>>> np.arange(a.shape[0])[~np.in1d(a,b)].tolist()
  [0, 1, 3]
like image 84
crs17 Avatar answered Oct 16 '22 08:10

crs17


It is quite easy, use numpy.intersect1d for calculating elements shared between a and b, then check which of those elements are not in a using numpy.in1d and finally get their position in the array using numpy.argwhere.

>>> import numpy as np
>>> a, b = np.array([13., 14., 15., 32., 33.]), np.array([15., 16., 17., 33., 34., 47.])
>>> np.argwhere(np.in1d(a, np.intersect1d(a,b)) == False)
array([[0],
   [1],
   [3]])

If you prefer a list just add .flatten to convert the matrix to a vector and then apply .tolist to get the list:

>>> np.argwhere(np.in1d(a, np.intersect1d(a,b)) == False).flatten().tolist()
 [0, 1, 3]
like image 38
jabaldonedo Avatar answered Oct 16 '22 08:10

jabaldonedo


Fairly straight forward if you use loops:

def difference_indices(a, b):

    # Set to put the unique indices in
    indices = []

    # So we know the index of the element of a that we're looking at
    a_index = 0

    for elem_a in a:

        found_in_b = False
        b_index = 0

        # Loop until we find a match. If we reach the end of b without a match, the current 
        # a index should go in the indices list
        while not found_in_b and b_index < len(b):
            if elem_a == b[b_index]: found_in_b = True
            b_index = b_index + 1

        if not found_in_b: indices.append(a_index)
        a_index = a_index + 1

    return indices

This should work with lists containing any one type, as long as they are the same type, and the __eq__ function is defined for that type.

Doing this without loops would require a knowledge of python greater than mine! Hope this is useful for you.

like image 1
AlexJ136 Avatar answered Oct 16 '22 08:10

AlexJ136