john
john

Reputation: 413

Delete 2D unique elements in a 2D NumPy array

I generate a set of unique coordinate combinations by using:

axis_1 = np.arange(image.shape[0])
axis_1 = np.reshape(axis_1,(axis_1.shape[0],1))

axis_2 = np.arange(image.shape[1])
axis_2 = np.reshape(axis_2,(axis_2.shape[0],1))


coordinates = np.array(np.meshgrid(axis_1, axis_2)).T.reshape(-1,2)

I then check for some condition and if it is satisfied i want to delete the coordinates from the array. Something like this:

if image[coordinates[i,0], coordinates[i,1]] != 0:
    remove coordinates i from coordinates

I tried the remove and delete commands but one doesn't work for arrays and the other simply just removes every instance where coordinates[i,0] and coordinates[i,1] appear, rather than the unique combination of both.

Upvotes: 0

Views: 69

Answers (2)

Tomi Aarnio
Tomi Aarnio

Reputation: 2517

You can use np.where to generate the coordinate pairs that should be removed, and np.unique combined with masking to remove them:

y, x = np.where(image > 0.7)
yx = np.column_stack((y, x))
combo = np.vstack((coordinates, yx))
unique, counts = np.unique(combo, axis=0, return_counts=True)
clean_coords = unique[counts == 1]

The idea here is to stack the original coordinates and the coordinates-to-be-removed in the same array, then drop the ones that occur in both.

Upvotes: 1

Jundiaius
Jundiaius

Reputation: 7668

You can use the numpy.delete function, but this function returns a new modified array, and does not modify the array in-place (which would be quite problematic, specially in a for loop).

So your code would look like that:

nb_rows_deleted = 0
for i in range(0, coordinates.shape[0]):
    corrected_i = i - nb_rows_deleted
    if image[coordinates[corrected_i, 0], coordinates[corrected_i, 1]] != 0:
        coordinates = np.delete(coordinates, corrected_i, 0)
        nb_rows_deleted += 1

The corrected_i takes into consideration that some rows have been deleted during your loop.

Upvotes: 0

Related Questions