1

I have two numpy arrays:

A.shape = (nA,x,y)

and

B.shape = (nB,x,y).

I want to find all subarrays such that

A(i,:,:) == B(j,:,:).

I know I can write a double for loop and use

np.array_equal(A(i,:,:),B(j,:,:)

However, is there a more efficient method?

3 Answers 3

1

You should only need to loop through one of the arrays, since you wouldn't find any additional unique subarrays after that, and you can do this with a simple list comprehension.

subarrays = [x for x in A if x in B]

If you only want the indices instead of storing the whole subarray, you can do:

indices = [x[0] for x in enumerate(A) if x[1] in B]
Sign up to request clarification or add additional context in comments.

2 Comments

Is there a way using the list comprehension to store the indices of the matches instead of the actual data?
Yep! Just edited my answer with how to do that, as well.
1

Utilizing Steven Rouk's solution, here is a method to get the indices for the subarrays that are equal:

indicesForMatches = [(i,j) for i,subArrayOfA in enumerate(A) for j,subArrayOfB in enumerate(B) if np.array_equal(subArrayOfA,subArrayOfB)]

Comments

1

You can use NumPy broadcasting for a vectorized solution, like so -

mask = ((A[:,None,:,:] == B).all(2)).all(2)
A_idx,B_idx = np.where(mask)

You can use reshaping to avoid double .all() usages and get the mask, like so -

mask = (A.reshape(A.shape[0],1,-1) == B.reshape(B.shape[0],-1)).all(-1)

Sample run -

In [41]: # Setup input arrays and force some indices to be same between A and B
    ...: nA = 4 
    ...: nB = 5
    ...: x = 3
    ...: y = 2
    ...: 
    ...: A = np.random.randint(0,9,(nA,x,y))
    ...: B = np.random.randint(0,9,(nB,x,y))
    ...: 
    ...: A[2,:,:] = B[1,:,:]
    ...: A[3,:,:] = B[4,:,:]
    ...: 

In [42]: mask = ((A[:,None,:,:] == B).all(2)).all(2)
    ...: A_idx,B_idx = np.where(mask)
    ...: 

In [43]: A_idx, B_idx
Out[43]: (array([2, 3]), array([1, 4]))

In [44]: mask = (A.reshape(A.shape[0],1,-1) == B.reshape(B.shape[0],-1)).all(-1)
    ...: A_idx,B_idx = np.where(mask)
    ...: 

In [45]: A_idx, B_idx
Out[45]: (array([2, 3]), array([1, 4]))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.