Replace all but the first 1 in an array with 0

Question:

I am trying to find a way to replace all of the duplicate 1 with 0. As an example:

[[0,1,0,1,0],
[1,0,0,1,0],
[1,1,1,0,1]]

Should become:

[[0,1,0,0,0],
[1,0,0,0,0],
[1,0,0,0,0]]

I found a similar problem, however the solution does not seem to work numpy: setting duplicate values in a row to 0

Asked By: jaceks123

||

Answers:

Try looping through each row of the grid

In each row, find all the 1s. In particular you want their indices (positions within the row). You can do this with a list comprehension and enumerate, which automatically gives an index for each element.

Then, still within that row, go through every 1 except for the first, and set it to zero.

grid = [[0, 1, 0, 1, 0], [1, 0, 0, 1, 0], [1, 1, 1, 0, 1]]

for row in grid:
    ones = [i for i, element in enumerate(row) if element==1]
    for i in ones[1:]:
        row[i] = 0

print(grid)

Gives: [[0, 1, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0]]

Answered By: Eureka

Assume array contains only zeros and ones, you can find the max value per row using numpy.argmax and then use advanced indexing to reassign the values on the index to a zeros array.

arr = np.array([[0,1,0,1,0],
[1,0,0,1,0],
[1,1,1,0,1]])

res = np.zeros_like(arr)
idx = (np.arange(len(res)), np.argmax(arr, axis=1))
res[idx] = arr[idx]

res
array([[0, 1, 0, 0, 0],
       [1, 0, 0, 0, 0],
       [1, 0, 0, 0, 0]])
Answered By: Psidom

You can use cumsum:

(arr.cumsum(axis=1).cumsum(axis=1) == 1) * 1

this will create a cummulative sum, by then checking if a value is 1 you can find the first 1s

Answered By: Andreas
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.