Here's a vectorized one with masking -
# nonzeros mask
nnz = A!=0
# Mask surrounded by nonzeros
max_accum = np.maximum.accumulate
island = max_accum(nnz,axis=1) & max_accum(nnz[:,::-1],axis=1)[:,::-1]
# Setup o/p array. Extract flipped A elements within each island per row and
# assign into sorted mask i.e. brought to front mask places in o/p
out = np.zeros_like(A)
out[np.sort(island, axis=1)[:,::-1]] = A[:,::-1][island[:,::-1]]
Explanation
Input array (for ref and a different one to handle corner case and better to explain) :
In [147]: A
Out[147]:
array([[ 1, 0, 2, 0, 0, 0, 0],
[ 0, 0, 0, 2, 4, 0, 6],
[ 5, 6, 7, 0, 9, 5, 10]])
Island mask of nonzeros-surrounded :
Forward accumulated mask
In [148]: max_accum(nnz,axis=1)
Out[148]:
array([[ True, True, True, True, True, True, True],
[False, False, False, True, True, True, True],
[ True, True, True, True, True, True, True]])
Backward accumulated mask with flipping nnz mask, performing forward accumulation, flipping back
In [149]: max_accum(nnz[:,::-1],axis=1)[:,::-1]
Out[149]:
array([[ True, True, True, False, False, False, False],
[ True, True, True, True, True, True, True],
[ True, True, True, True, True, True, True]])
Final combined mask to give us island
In [150]: max_accum(nnz,axis=1) & max_accum(nnz[:,::-1],axis=1)[:,::-1]
Out[150]:
array([[ True, True, True, False, False, False, False],
[False, False, False, True, True, True, True],
[ True, True, True, True, True, True, True]])
Selection and assignment :
In [159]: A
Out[159]:
array([[ 1, 0, 2, 0, 0, 0, 0],
[ 0, 0, 0, 2, 4, 0, 6],
[ 5, 6, 7, 0, 9, 5, 10]])
In [160]: island
Out[160]:
array([[ True, True, True, False, False, False, False],
[False, False, False, True, True, True, True],
[ True, True, True, True, True, True, True]])
In [161]: A[:,::-1]
Out[161]:
array([[ 0, 0, 0, 0, 2, 0, 1],
[ 6, 0, 4, 2, 0, 0, 0],
[10, 5, 9, 0, 7, 6, 5]])
In [162]: island[:,::-1]
Out[162]:
array([[False, False, False, False, True, True, True],
[ True, True, True, True, False, False, False],
[ True, True, True, True, True, True, True]])
Hence, select :
In [165]: A[:,::-1][island[:,::-1]]
Out[165]: array([ 2, 0, 1, 6, 0, 4, 2, 10, 5, 9, 0, 7, 6, 5])
To select brought-to-front mask, sort island mask, which selects o/p places to be assigned into :
In [163]: np.sort(island, axis=1)[:,::-1]
Out[163]:
array([[ True, True, True, False, False, False, False],
[ True, True, True, True, False, False, False],
[ True, True, True, True, True, True, True]])
Then, assign those A selected ones into output with sorted mask :
In [166]: out
Out[166]:
array([[ 2, 0, 1, 0, 0, 0, 0],
[ 6, 0, 4, 2, 0, 0, 0],
[10, 5, 9, 0, 7, 6, 5]])