using indexing
You can get the negative indices at the positions of the 1s (and the last), then backfill using a reverse cumulated minimum:
idx = np.minimum.accumulate(np.where(a[1], np.arange(-a.shape[1], 0), -1)[::-1])[::-1]
# array([-8, -8, -8, -5, -5, -5, -1, -1, -1, -1])
a[2] = a[0, idx]
Step by step intermediates to construct idx (where _ denote the previous command):
np.arange(-a.shape[1], 0)
# array([-10, -9, -8, -7, -6, -5, -4, -3, -2, -1])
np.where(a[1], _, -1)
# array([-1, -1, -8, -1, -1, -5, -1, -1, -1, -1])
np.minimum.accumulate(_[::-1])[::-1]
# array([-8, -8, -8, -5, -5, -5, -1, -1, -1, -1])
Same logic with positive indexing:
idx = np.minimum.accumulate(
np.where(a[1], np.arange(a.shape[1]), a.shape[1] - 1)[::-1]
)[::-1]
a[2] = a[0, idx]
Intermediates:
np.arange(a.shape[1])
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.where(a[1], _, a.shape[1]-1)
# array([9, 9, 2, 9, 9, 5, 9, 9, 9, 9])
np.minimum.accumulate(_[::-1])[::-1]
# array([2, 2, 2, 5, 5, 5, 9, 9, 9, 9])
Here we get the indices of the 1s (and the last position), compute the number of items to repeat
idx = np.where(np.r_[a[1, :-1], 1])[0]
# array([2, 5, 9])
a[2] = np.repeat(a[0, idx], np.diff(np.r_[-1, idx]))
# np.repeat([5, 8, 6], [3, 3, 4])
import pandas as pd
a[2] = pd.Series(a[0]).where(np.r_[a[1, :-1]==1, True]).bfill()
Output
array([[3, 4, 5, 6, 7, 8, 9, 8, 7, 6],
[0, 0, 1, 0, 0, 1, 0, 0, 0, 0],
[5, 5, 5, 8, 8, 8, 6, 6, 6, 6]])