Vladislav Ladenkov Vladislav Ladenkov - 25 days ago 7
Python Question

Efficiantly change matrix's elements at special positions

I have a matrix like:

0001111111110
0010000000001
0100000000010
0100000000010
0010000000001
0011111111110


I want it to fill inner zeros with ones:

0001111111110
0011111111111
0111111111110
0111111111110
0011111111111
0011111111110


There are a lot of matrixes and they are large.

I have only 1 idea for this moment:

for i, row in enumerate(mask):
if sum(row) > 0:
top_one = np.argmax(row)
bot_one = len(row) - np.argmax(row[::-1]) - 1
mask[i, top_one:bot_one] = 1


There can be only ONE inner zeros zone!(easy case)

I want the most efficiant and beautiful solution, please

EDIT: Why doesnt the
scipy
methos work?

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

scipy.ndimage.binary_fill_holes(a).astype(int)
array([[0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0]])

Answer

there is a function in scipy.ndimage to do that:

scipy.ndimage.binary_fill_holes(mask).astype(int)

results in

array([[0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
       [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]])