I want to use a built in numpy function to compare 2 arrays of pixel coordinates from a 3D image(ndarray), to see which points with a particular flag in image1 have a specific flag at the same coordinate in image2. Image1 and Image2 are the same size (both masks over an original 3D image). Right now I am using a for loop to compare which is quite inefficient. Is there a numpy method or a more efficient method to do this? I am unsure if I need to column stack as I have done below.
Code:
array1 = np.where(image1 == label1)
array2 = np.where(image2 == label2)
coordinates = []
temp1 = np.column_stack((array1[0],array1[1],array1[2]))
temp2 = np.column_stack((array2[0],array2[1],array2[2]))
for i, element in enumerate(temp1):
if element in temp2:
coordinates.append(element)
CodePudding user response:
You have to iterate, but using list comprehension makes it faster
mask = [ (element in temp2) for element in temp1]
coordinates = temp1[mask]
CodePudding user response:
Broadcast comparison:
comp = temp2[None] == temp1[:, None]
This is equivalent to:
comp = np.array([[a1 == a2 for a2 in temp2] for a1 in temp1])
Then use ndarray.all
and ndarray.any
:
comp.all(-1).any(0)
Test:
>>> r = np.random.rand(20, 3)
>>> a1 = r[::2]
>>> a2 = r[:10]
>>> (a2[None] == a1[:, None]).all(-1).any(0)
array([ True, False, True, False, True, False, True, False, True,
False])
Note:
For numpy arrays, it is incorrect to use keyword in
to find whether a 1d array is a row of a 2d array, it is equivalent to judging whether any number in 1d array is in 2d array:
>>> a2d = np.random.rand(3, 3)
>>> np.array([a2d[0, 0], np.nan, np.nan]) in a2d
True