3

I want to find multiple matching rows from 2d array a

a = np.array([[2, 1],
          [3, 3],
          [4, 6],
          [4, 8],
          [4, 7],
          [4, 3]])

I have to search following entries

 b = np.array([[4,6],
          [4,7]])

I know that I can loop over b and do following

for i in range(len(b)) :
   print(np.where(np.all(a==b[i],axis=1))[0])

And I get following

[2]
[4]

Can I get [[2],[4]] directly without using any loop?

2 Answers2

5

If you want the indices you will generally reach for the arg_x functions like argmax and argwhere. Here np.argwhere will give you the indices if you can figure out how to pass the correct list of booleans. You can do that with np.isin():

a = np.array([[2, 1],
          [3, 3],
          [4, 6],
          [4, 8],
          [4, 7],
          [4, 3]])

b = np.array([[4,6], [4,7]])

np.argwhere(np.isin(a, b).all(axis=1))

Which returns:

array([[2],
       [4]])
Mark
  • 90,562
  • 7
  • 108
  • 148
  • This is what I was looking for, elegant and simple to understand. thanks ! – sandy.perception Jun 29 '20 at 05:26
  • 3
    I believe this works by chance (since the second row contains only unique elements), doesnt it? If the first row was [2,6] this would also match it and return the 0 index – Banana May 19 '22 at 20:02
  • You are a savior. Thank you so much! – McLovin Nov 10 '22 at 03:29
  • 1
    This answer is wrong and should not be accepted ! `np.isin()` check each elements individually. For example if the row `[6,7]` is present in `a` then this row will be returned as a matching row ! – obchardon Feb 13 '23 at 09:37
0

This should be a fast solution noticing that the two pairs have the same first coordinate:

np.where((a[:, 0] == 4) & ((a[:, 1] == 6) | (a[:, 1] == 7)))  
# Out:
# (array([2, 4]),)

The expression

print((a[:, 0] == 4) & ((a[:, 1] == 6) | (a[:, 1] == 7)))                                    

gives

[False False  True False  True False] 
user2314737
  • 27,088
  • 20
  • 102
  • 114