Return last not null value before nan occurrences

Viewed 56

I have a series 's' with null and not null values:

s = pd.Series([np.nan, 5, 4, 2, np.nan, np.nan, 4, 3, np.nan])

I need to obtain 's1' returned last not null value before each np.nan:

s1 = [np.nan, np.nan, np.nan, 2, np.nan, np.nan, np.nan, 3, np.nan]

Many thanks in advance.

Regards Tom

3 Answers

Let's create a grouper using Series.isna + Series.cumsum to identify continuous blocks of non NaN values, then groupby the series on this grouper and transform using last finally mask the values which are duplicated in the grouper:

g = s.isna().cumsum()
s1 = s.groupby(g).transform('last').mask(g.duplicated(keep='last'))

Result:

print(s1)

0    NaN
1    NaN
2    NaN
3    2.0
4    NaN
5    NaN
6    NaN
7    3.0
8    NaN
dtype: float64
s1 = []
for i in range(len(s)-1):
    if s[i+1] == np.nan:
        s1.append(s[i])

Taking a cue from @ShubamSharma's answer, get the rows that are null, convert to type int, get the difference between 1 and 0, working your way from the bottom (since we are looking for the last non null value before nan), and finally use np.where to get our result:

s1 = np.where(s.isna().astype(int).diff(-1).eq(-1), s, np.nan)
s1
array([nan, nan, nan,  2., nan, nan, nan,  3., nan])
Related