Centre all columns of an array
review

comparison

no need to compare against True or False. (begin == True) can be easier expressed as begin and (end == False) as not end. and comparison chaining is done with and, not &amp;(bitwise and)

iteration

In python, it is very seldomly needed to iterate over the indices. Instead of for y in range(len(array)): and for x in range(len(array[0])), you can do

for row in array:
    ...
    for x, element in enumerate(row):
        if element == 0 and begin and not end:


alternative solution

try to vectorise as much as possible. The easiest thing to do is count the zeroes in front and at the back:

def count_zeroes(array):
    return (array.cumsum(axis=1) == 0).sum(axis=1)

zeroes_front = count_zeroes(array)


and then the same for the reverse:

zeroes_back = count_zeroes(test_data[:,::-1])


The amount each row needs to roll is:

roll = (zeroes_front + zeroes_back) //2 - zeroes_front



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



and then you apply this roll over each row:

np.array([np.roll(row, r) for row, r in zip(test_data, roll)])



array([[0.   , 0.149, 0.064, 0.736, 0.   ],
       [0.   , 0.258, 0.979, 0.618, 0.   ],
       [0.   , 0.786, 0.666, 0.   , 0.   ],
       [0.   , 0.782, 0.954, 0.   , 0.   ]])



in total:

def centre(array):
    zeroes_front = count_zeroes(array)
    zeroes_back = count_zeroes(array[:,::-1])
    roll = (zeroes_front + zeroes_back) //2 - zeroes_front
    return np.array([np.roll(row, r) for row, r in zip(array, roll)])