0

I have a matrix that looks like this:

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

and I want to change it in a way, that if there is 1 value in a row, then make two rows above and after to 1 as well, so the output should be:

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

any idea or help please?

thank you

3
  • Are you able to use SciPy? Commented Jan 12, 2017 at 9:46
  • @ajcr yes I can Commented Jan 12, 2017 at 9:52
  • The binary_dilation function with an appropriate array for the 'structure' kwarg might be a good option in that case. Commented Jan 13, 2017 at 12:58

3 Answers 3

1
for (x,y) in np.argwhere(n==1):
    xfrom=max(x-2,0)
    xto=min(n.shape[0]-1,x+2)
    for i in range(xfrom, xto+1):
        n[i,y]=1
Sign up to request clarification or add additional context in comments.

2 Comments

what is the n? is it the matrix? if so, I get an error of index out of bounds
You're right. n - matrix, I corrected the upper bound to n.shape[0]-1. Sorry for that.
0

When dealing with an array of 0s and 1s, you may want to convert it to an boolean array and make use of the logical operators. And, slicing and indexing in numpy is very handy.

def expand_in_place(bool_matrix, expand_up=2, expand_down=2):
    assert expand_up >= 0 and expand_down >= 0

    # expands upward
    for _ in range(expand_up):
        bool_matrix[:-1] |= bool_matrix[1:].copy()

    # expands downward
    for _ in range(expand_down):
        bool_matrix[1:] |= bool_matrix[:-1].copy()

Example usage:

matrix = np.array([[0, 0, 0, 0],
                   [0, 0, 0, 0],
                   [0, 1, 0, 0],
                   [0, 0, 0, 0],
                   [0, 0, 0, 0],
                   [0, 0, 0, 0],
                   [0, 0, 0, 0],
                   [0, 0, 0, 0],
                   [0, 0, 0, 0],
                   [0, 0, 1, 0],
                   [0, 0, 0, 0]])
bool_matrix = matrix.astype(bool)
expand_in_place(bool_matrix)
print()  # newline
print(bool_matrix.astype(int))

Output:

In [64]: 
[[0 1 0 0]
 [0 1 0 0]
 [0 1 0 0]
 [0 1 0 0]
 [0 1 0 0]
 [0 0 0 0]
 [0 0 0 0]
 [0 0 1 0]
 [0 0 1 0]
 [0 0 1 0]
 [0 0 1 0]]

Explanation:

  1. The key is what happens when you call bool_matrix[:-1] |= bool_matrix[1:] every time.
  2. I add .copy() because bool_matrix[1:] |= bool_matrix[:-1] doesn't work as expected.

    In [108]: small = np.array([False, False, True, False, False])
    
    In [109]: small[1:] |= small[:-1]
    
    In [110]: small
    Out[110]: 
    array([False, False,  True,  True,  True], dtype=bool)
    
  3. You can easily extend it to expand in four directions.

Comments

0

Much easier:

for row, col in np.argwhere(n == 1):
    n[row-2:row+3,col] = 1

Let Python's and NumPy's slicing semantics work for you. No need to calculate boundaries.

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.