Search code examples
pythonnumpycoordinatesnumpy-ndarray

How to match pairs of values contained in two numpy arrays


I have two sets of coordinates and want to find out which coordinates of the coo set are identical to any coordinate in the targets set. I want to know the indices in the coo set which means I'd like to get a list of indices or of bools.

import numpy as np

coo = np.array([[1,2],[1,6],[5,3],[3,6]]) # coordinates
targets = np.array([[5,3],[1,6]]) # coordinates of targets

print(np.isin(coo,targets))

[[ True False]
 [ True  True]
 [ True  True]
 [ True  True]]

The desired result would be one of the following two:

[False True True False] # bool list
[1,2] # list of concerning indices

My problem is, that ...

  • np.isin has no axis-attribute so that I could use axis=1.
  • even applying logical and to each row of the output would return True for the last element, which is wrong.

I am aware of loops and conditions but I am sure Python is equipped with ways for a more elegant solution.


Solution

  • This solution will scale worse for large arrays, for such cases the other proposed answers will perform better.


    Here's one way taking advantage of broadcasting:

    (coo[:,None] == targets).all(2).any(1)
    # array([False,  True,  True, False])
    

    Details

    Check for every row in coo whether or not it matches another in target by direct comparisson having added a first axis to coo so it becomes broadcastable against targets:

    (coo[:,None] == targets)
    
    array([[[False, False],
            [ True, False]],
    
           [[False, False],
            [ True,  True]],
    
           [[ True,  True],
            [False, False]],
    
           [[False, False],
            [False,  True]]])
    

    Then check which ndarrays along the second axis have all values to True:

    (coo[:,None] == targets).all(2)
    
    array([[False, False],
           [False,  True],
           [ True, False],
           [False, False]])
    

    And finally use any to check which rows have at least one True.