I have two arrays, say:
a, b = np.array([13., 14., 15., 32., 33.]), np.array([15., 16., 17., 33., 34., 47.])
I need to find the indices of all the elements in a that are not present in b. In the above example the result would be:
[0, 1, 3]
Because a[0], a[1] and a[3] are 13., 14. and 32., which are not present in b. Notice that I don't care to know the actual values of 13., 14. and 32. (I could have used set(a).difference(set(b)), in that case). I am genuinely interested in the indices only.
If possible the answer should be "vectorized", i.e. not using a for loop.
Step 1: Import numpy. Step 2: Define two numpy arrays. Step 3: Find intersection between the arrays using the numpy. intersect1d() function.
Method 1: We generally use the == operator to compare two NumPy arrays to generate a new array object. Call ndarray. all() with the new array object as ndarray to return True if the two NumPy arrays are equivalent.
To find the intersection of between two arrays, use the bitwise and (&) between the sets of given arrays and assign it into a variable Y in the form of lists. Print variable X and Y which is our required output.
You could use np.in1d:
>>> np.arange(a.shape[0])[~np.in1d(a,b)].tolist()
[0, 1, 3]
It is quite easy, use numpy.intersect1d
for calculating elements shared between a
and b
, then check which of those elements are not in a
using numpy.in1d
and finally get their position in the array using numpy.argwhere
.
>>> import numpy as np
>>> a, b = np.array([13., 14., 15., 32., 33.]), np.array([15., 16., 17., 33., 34., 47.])
>>> np.argwhere(np.in1d(a, np.intersect1d(a,b)) == False)
array([[0],
[1],
[3]])
If you prefer a list just add .flatten
to convert the matrix to a vector and then apply .tolist
to get the list:
>>> np.argwhere(np.in1d(a, np.intersect1d(a,b)) == False).flatten().tolist()
[0, 1, 3]
Fairly straight forward if you use loops:
def difference_indices(a, b):
# Set to put the unique indices in
indices = []
# So we know the index of the element of a that we're looking at
a_index = 0
for elem_a in a:
found_in_b = False
b_index = 0
# Loop until we find a match. If we reach the end of b without a match, the current
# a index should go in the indices list
while not found_in_b and b_index < len(b):
if elem_a == b[b_index]: found_in_b = True
b_index = b_index + 1
if not found_in_b: indices.append(a_index)
a_index = a_index + 1
return indices
This should work with lists containing any one type, as long as they are the same type, and the __eq__
function is defined for that type.
Doing this without loops would require a knowledge of python greater than mine! Hope this is useful for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With