Home > other >  Numpy version of this for loop?
Numpy version of this for loop?

Time:07-24

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
  • Related