Reputation: 205
I have two numpy array
a= np.array([[2,2],[3,2],[4,2],[3,3],[5,3]])
b= np.array([[1,1],[1,3],[5,3]])
I want to compare a with b and return a-b such that :
a-b = array([[2,2],
[3,2],
[4,2],
[3,3]])
I have tried doing :
[x for x in a if x not in b]
and it resulted in
[array([2, 2]), array([3, 2]), array([4, 2])] # where clearly [3,3] is missing
I even tried comparing each row of both a and b within loop where it gave me an error
The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Can anyone please help me to solve this problem ???
Upvotes: 1
Views: 82
Reputation: 221754
Broadcasting
based vectorized approach -
a[~((b[:,None,:] == a).all(2)).any(0)]
Using cdist
from scipy.spatial.distance
-
from scipy.spatial.distance import cdist
a[~(cdist(a,b)==0).any(1)]
Sample run -
In [89]: a
Out[89]:
array([[2, 2],
[3, 2],
[4, 2],
[3, 3],
[5, 3]])
In [90]: b
Out[90]:
array([[1, 1],
[1, 3],
[5, 3]])
In [91]: a[~((b[:,None,:] == a).all(2)).any(0)]
Out[91]:
array([[2, 2],
[3, 2],
[4, 2],
[3, 3]])
In [92]: a[~(cdist(a,b)==0).any(1)]
Out[92]:
array([[2, 2],
[3, 2],
[4, 2],
[3, 3]])
Upvotes: 2
Reputation: 91009
One way to do this would be to convert the numpy arrays into list of tuples and b
to set of tuples then do the same list comprehension you used on them. Example -
In [1]: import numpy as np
In [2]: a= np.array([[2,2],[3,2],[4,2],[3,3],[5,3]])
In [3]: b= np.array([[1,1],[1,3],[5,3]])
In [18]: alist = list(map(tuple, a))
In [19]: bset = set(map(tuple, b))
In [20]: np.array([x for x in alist if x not in bset])
Out[20]:
array([[2, 2],
[3, 2],
[4, 2],
[3, 3]])
Upvotes: 1