Development of my comment:
Expand pairs to be more interesting. Feel free to test with a larger, more realistic array:
In [260]: pairs = np.array([[[1,2,4],[3,4,4]],[[1,2,5],[5,6,5]],[[3,4,5],[3,5,6]],[[6,7,5],[1,2,3]]]) In [261]: positions = np.array([[ 1, 2, 4], [ 3, 4, 5], [ 5, 6, 3], [ 3, 5, 6], [ 6, 7, 5], [12, 2, 5]])
Expand both arrays into broadcast forms:
In [262]: I = pairs[None,...]==positions[:,None,None,:] In [263]: I.shape Out[263]: (6, 4, 2, 3)
A large logical array that displays elements by elements in all dimensions. Could not replace other comparisons ( difference ==0 , np.isclose for floats, etc.).
In [264]: J = I.all(axis=-1).any(axis=0).sum(axis=-1) In [265]: J Out[265]: array([1, 0, 2, 1])
Consolidation of results by various parameters. Match all numbers by coordinates, match any positions, count matches in pairs.
In [266]: pairs[J==1,...] Out[266]: array([[[1, 2, 4], [3, 4, 4]], [[6, 7, 5], [1, 2, 3]]])
J==1 represent elements in which only one value of the pair matches. (see note)
The combination of any , and and sum works for a test case, but adjustment with a larger test case may be required. But the idea is generally applicable.
For the size of arrays that are fooobar.com/questions/829351 / ... , my solution is rather slow. In particular, he performs the test == , which leads to I with the form (5000, 5000, 2, 3) .
Squeezing the last measurement helps a lot
dims = np.array([10000,100,1])
I changed the expression of J1d according to mine - to count the number of matches per pair.
in1d1 , which uses Divakar , is even faster:
mask = np.in1d(pairs1D, positions1D).reshape(-1,2) Jmask = mask.sum(axis=-1)
I just realized that the OP is asking at most one of the pairs is in the positions array . Where I test exactly one match per pair . So, my tests should be changed to pairs[J<2,...] .
(in my specific random sample for n = 5000, which, as it turned out, is everything. There are no pairs where both are in positions . 54 out of 5000 have J==1 , the rest 0, there are no matches).