0

To illustrate my point, lets take this 2d numpy array:

array([[1, 1, 5, 1, 1, 5, 4, 1],
       [1, 5, 6, 1, 5, 4, 1, 1],
       [5, 1, 5, 6, 1, 1, 1, 1]])

I want to replace the value 1 with some other value, let's say 0, but only at the edges. This is the desired result:

array([[0, 0, 5, 1, 1, 5, 4, 0],
       [0, 5, 6, 1, 5, 4, 0, 0],
       [5, 1, 5, 6, 0, 0, 0, 0]])

Note that the 1's surrounded by other values are not changed.

I could implement this by iterating over every row and element, but I feel like that would be very inefficient. Normally I would use the np.where function to replace a specific value, but I don't think you can add positional conditions?

4
  • Related: stackoverflow.com/questions/41200719/how-to-get-all-array-edges , Another one: stackoverflow.com/questions/60811307/… Commented Mar 23, 2020 at 10:32
  • 3
    @Ch3steR The OP is misleading by calling it edges. The example demonstrates that you start from the corners and propagate until you hit a value not equal to 1. So the thickness of the "edge" may be more than 1 row/column and it can also be that an element in the proper edges is not affected. Commented Mar 23, 2020 at 10:49
  • Can you tell us what problem you're trying to solve? There might be a better by representing your data differently. Also, how big is your array? Based on how it's been stated so far, I can't think of a better way than some form of iterative process. Also, is 0 likely to be part of your normal data? Commented Mar 23, 2020 at 10:52
  • @Reti43 Sorry if my question was a bit vague, I thought the example would be sufficient. The problem is that I have a lot of images with some kind of padding with a gray value of 168 (as seen in the example with 1's). But these are not just constant borders with a fixed size: they vary per row. I want to set these 'border' values to 0. However, if I set all 168 values in the array to 0, there will also be a lot of pixels inside the image that get changed to 0, which is not something I want. Commented Mar 23, 2020 at 11:04

1 Answer 1

3
m = row!=1   
w1 = m.argmax()-1
w2 = m.size - m[::-1].argmax()

These three lines will give you the index for the trailling ones. The idea has been taken from trailing zeroes.

Try:

arr = np.array([[1, 1, 5, 1, 1, 5, 4, 1],
       [1, 5, 6, 1, 5, 4, 1, 1],
       [5, 1, 5, 6, 1, 1, 1, 1]])

for row in arr:
    m = row!=1

    w1 = m.argmax()-1
    w2 = m.size - m[::-1].argmax()
#     print(w1, w2)
    row[0:w1+1] = 0
    row[w2:] = 0
#     print(row)

arr:

array([[0, 0, 5, 1, 1, 5, 4, 0],
       [0, 5, 6, 1, 5, 4, 0, 0],
       [5, 1, 5, 6, 0, 0, 0, 0]])
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.