1

I have a numpy array - image with various values: example image = [1 ,2 ,2, 3, 4, 4, 4, 4, 5, 6, 6 ,7 ,8 ,8 ,8 ,8] I want to replace only those numbers occurring less than twice - by a specific number, let's say 0. I managed to create the list of those numbers like this:

(unique, counts) = np.unique(image, return_counts=True)
frequencies = np.asarray((unique, counts)).T
freq = frequencies[frequencies[:,1] < 2,0]
print(freq)
array([1, 3, 5, 7], dtype=int64)

How do I replace those numbers by zero?

the outcome should look like : [0 ,2 ,2, 0, 4, 4, 4, 4, 0, 6, 6 ,0 ,8 ,8 ,8 ,8]

Thanks in advance!

2 Answers2

0

If both image and freq are numpy arrays:

freq = np.array([1, 3, 5, 7])
image = np.array([1 ,2 ,2, 3, 4, 4, 4, 4, 5, 6, 6 ,7 ,8 ,8 ,8 ,8])

Solution 1

You can then find the indices of image entries appearing in freq, then set them to zero:

image[np.argwhere(np.isin(image, freq)).ravel()] = 0

Based on: Get indices of items in numpy array, where values is in list.


Solution 2

Use np.in1d:

image = np.where(np.in1d(image,freq),0,image)

More info: Numpy - check if elements of a array belong to another array


Solution 3

You can also use a list comprehension:

image = [each if each not in freq else 0 for each in image]

Can find more info here: if/else in a list comprehension.


The last one will result in a list, not a numpy array, but other than that, all of these yield the same result.

zabop
  • 6,750
  • 3
  • 39
  • 84
  • Thanks a lot for the quick response works like a charm with the example, but with my image I get: "\ipykernel_launcher.py:4: DeprecationWarning: elementwise comparison failed; this will raise an error in the future." I checked the image and the values stayed as in the original – Daniel Suske Nov 19 '21 at 22:03
  • Rewritten my answer, removing the confusing thing about `res`. – zabop Nov 19 '21 at 22:16
  • Thanks for the explanation! I tried all of them. But none of them works as I expected. I guess it worked for the first row of the image though. The image is about 500 rows by 500 cols, sorry for not clarifying this sooner – Daniel Suske Nov 19 '21 at 22:29
  • Oh, your `image` array is multidimensional? Sadly this means that these solutions aren't going to work. – zabop Nov 19 '21 at 22:32
  • I recommend asking a new question emphasizing that arrays are multidimensional, with arrays similar to your real arrays (ie they should have the same number of dimensions) - other people are probably going to assume what I did unless they are reading these comments. – zabop Nov 19 '21 at 22:34
0

You could compare each item to the rest of the array to form a 2D matrix and sum each count. Then assign the items meeting the frequency condition with the desired value:

import numpy as np

img = np.array([1 ,2 ,2, 3, 4, 4, 4, 4, 5, 6, 6 ,7 ,8 ,8 ,8 ,8])

img[np.sum(img==img[:,None],axis=1)<2] = 0

array([0, 2, 2, 0, 4, 4, 4, 4, 0, 6, 6, 0, 8, 8, 8, 8])

Probably not very efficient but it should work.

Alain T.
  • 40,517
  • 4
  • 31
  • 51