Approach #1
Here's one based on this post
-
def fill_by_last_val(a):
lens = np.array([len(item) for item in a])
ncols = lens.max()
last_ele = np.array([a_i[-1] for a_i in a])
out = np.repeat(last_ele[:,None],ncols,axis=1)
mask = lens[:,None] > np.arange(lens.max())
out[mask] = np.concatenate(a)
return out
Approach #2
Another based on itertools
-
import itertools
def fill_by_last_val_v2(a):
last_ele = np.array([a_i[-1] for a_i in a])
a_f = np.array(list(itertools.zip_longest(*a,fillvalue=0))).T
m = np.minimum.accumulate((a_f==0)[:,::-1],axis=1)[:,::-1]
return m*last_ele[:,None]+a_f
Approach #3
Another with pandas
dataframe assuming no NaNs
in the input -
import pandas as pd
def fill_by_last_val_v3(a):
df = pd.DataFrame(a)
m = df.isnull()
last_ele = np.array([a_i[-1] for a_i in a])
return np.where(m,last_ele[:,None],df)
Approach #4
Simplest of the lot with pandas
again -
In [168]: a
Out[168]: [[255, 255, 255, 5], [128, 5, 6], [34, 0, 7], [nan, 44]]
In [169]: pd.DataFrame(a).ffill(axis=1).to_numpy()
Out[169]:
array([[255., 255., 255., 5.],
[128., 5., 6., 6.],
[ 34., 0., 7., 7.],
[ nan, 44., 44., 44.]])
You might want to do dtype conversion though to have the original datatype for pandas
solutions.