Intersection of 2d and 1d Numpy array Intersection of 2d and 1d Numpy array numpy numpy

Intersection of 2d and 1d Numpy array


If you feed in that sliced 2D array A[:,3:] to np.in1d, it would flatten it to a 1D array and compare with B for occurrences and thus create a 1D mask, which could be reshaped and used for boolean indexing into that sliced array to set the TRUE elements to zeros. A one-liner implementation would look something like this -

A[:,3:][np.in1d(A[:,3:],B).reshape(A.shape[0],-1)] = 0

Sample run -

In [37]: AOut[37]: array([[  1,   1,  10, 101, 102, 103,   0,   0],       [  2,   2,  10, 102, 108,   0,   0,   0],       [  3,   3,  11, 101, 102, 106, 107, 108]])In [38]: np.in1d(A[:,3:],B) # Flattened maskOut[38]: array([ True, False, False, False, False, False,  True, False, False,       False,  True, False,  True, False,  True], dtype=bool)In [39]: np.in1d(A[:,3:],B).reshape(A.shape[0],-1) # Reshaped maskOut[39]: array([[ True, False, False, False, False],       [False,  True, False, False, False],       [ True, False,  True, False,  True]], dtype=bool)In [40]: A[:,3:][np.in1d(A[:,3:],B).reshape(A.shape[0],-1)] = 0 # Final codeIn [41]: AOut[41]: array([[  1,   1,  10,   0, 102, 103,   0,   0],       [  2,   2,  10, 102,   0,   0,   0,   0],       [  3,   3,  11,   0, 102,   0, 107,   0]])

To make things simpler, you could create a view of the flattened A and use the 1D mask obtained from np.in1d to have a more elegant solution. For a solution that changes only the sliced A[:,3:], you can use .flat and then index like so -

A[:,3:].flat[np.in1d(A[:,3:],B)] = 0

For a case when you would like to set matching ones across entire A, you can use .ravel() -

A.ravel()[np.in1d(A,B)] = 0

I know .ravel() is a view and from the docs, it seems .flat doesn't create a copy either, so these should be cheap.


Here's a way to do this without using in1d(). You can use the regular Python in operator with a ravel-ed version of your array:

listed = [aa  in B for aa in A[:, 3:].ravel()]# mask for unaffected left columns of Amask1 = np.array([False]*A.shape[0]*3)mask1.shape = (A.shape[0], 3)# mask for affected right columns of Amask2 = np.array(listed)mask2.shape = (A.shape[0], A.shape[1]-3)# join masks together so you have a mask with same dimensions as Amask = np.hstack((mask1, mask2))result  = A.copy()result[mask] = 0

Or more succinctly:

listed = [aa  in B for aa in A[:, 3:].ravel()]listed_array = np.array(listed)listed.shape = (A.shape[0], A.shape[1]-3)A[:, 3:][listed_array] = 0

You're probably better off with in1d() but it's nice to know there are other options.