1

I have a 2D numpy array filled with 0 and 1, and I would like to transform it so that every value neighboring a 1 is transformed to a 1 (hence the "contamination" in the title).

For example :

0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 1 0 0
0 0 0 0 1 0
0 0 1 0 0 0
0 0 0 0 0 0

Becomes :

0 0 0 0 0 0
0 0 1 1 1 0
0 0 1 1 1 1
0 1 1 1 1 1
0 1 1 1 1 1
0 1 1 1 0 0

I can achieve this by looping through all the values, finding the 1s, and then replacing the adjacent values :

import numpy as np

ones = []

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

n_row, n_col = ar.shape

for i in range(n_row):
    for j in range(n_col):

        if ar[i][j] == 1:
            ones.append((i, j))

for x,y in ones:
    # Replace neighboring values

But this seems overkill (especially because I'm planning to deal with really large arrays).

Is there a way to achieve this without having to loop through all the values ?

2 Answers 2

2

That's basically dilation operation in Image-processing domain. So, you can use Scipy's binary dilation -

from scipy.ndimage import binary_dilation
out = binary_dilation(arr, structure=np.ones((3,3))).astype(int)

Sample run -

In [21]: arr
Out[21]: 
array([[0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 0, 1, 0, 0],
       [0, 0, 0, 0, 1, 0],
       [0, 0, 1, 0, 0, 0],
       [0, 0, 0, 0, 0, 0]])

In [22]: binary_dilation(arr, structure=np.ones((3,3))).astype(int)
Out[22]: 
array([[0, 0, 0, 0, 0, 0],
       [0, 0, 1, 1, 1, 0],
       [0, 0, 1, 1, 1, 1],
       [0, 1, 1, 1, 1, 1],
       [0, 1, 1, 1, 1, 1],
       [0, 1, 1, 1, 0, 0]])
Sign up to request clarification or add additional context in comments.

Comments

0

The operation that you described is known as "binary dilation". There is an implementation in scipy.ndimage. For example,

In [369]: a
Out[369]: 
array([[0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 0, 1, 0, 0],
       [0, 0, 0, 0, 1, 0],
       [0, 0, 1, 0, 0, 0],
       [0, 0, 0, 0, 0, 0]])

In [370]: from scipy.ndimage import binary_dilation

In [371]: binary_dilation(a, structure=np.ones((3, 3)))
Out[371]: 
array([[False, False, False, False, False, False],
       [False, False,  True,  True,  True, False],
       [False, False,  True,  True,  True,  True],
       [False,  True,  True,  True,  True,  True],
       [False,  True,  True,  True,  True,  True],
       [False,  True,  True,  True, False, False]], dtype=bool)

In [372]: binary_dilation(a, structure=np.ones((3, 3))).astype(int)
Out[372]: 
array([[0, 0, 0, 0, 0, 0],
       [0, 0, 1, 1, 1, 0],
       [0, 0, 1, 1, 1, 1],
       [0, 1, 1, 1, 1, 1],
       [0, 1, 1, 1, 1, 1],
       [0, 1, 1, 1, 0, 0]])

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.