Skip to content
Advertisement

Pandas fillna based on a condition

I’m still new to pandas, but I have a dataframe in the following format:

    d_title    d_prefix                            d_header d_country d_subtitles  d_season  d_episode
0        NaN        NaN                 ##### MOROCCO #####   Morocco         NaN       NaN        NaN
1     title1         AR                                 NaN       NaN         NaN       NaN        NaN
2     title2         AR                                 NaN       NaN         NaN       NaN        NaN
3        NaN        NaN               ##### MOROCCO 2 #####   Morocco         NaN       NaN        NaN
4     title3         AR                                 NaN       NaN         NaN       NaN        NaN
5        NaN        NaN                 ##### ALGERIA #####   Algeria         NaN       NaN        NaN
6     title4         AR                                 NaN       NaN         NaN       NaN        NaN
7     title5         AR                                 NaN       NaN         NaN       NaN        NaN
8     title6         IT                                 NaN       NaN         NaN       NaN        NaN
9     title7         PL                                 NaN       NaN         NaN       1.0        1.0
10    title8         UK                                 NaN       NaN         NaN       NaN        NaN
11    title9         UK                                 NaN       NaN         NaN       NaN        NaN

and I’m trying to fill all NaN fields in the ‘d_header’ column using the following conditions:

  • ‘d_header’ column should be set only for rows belonging to the same group
  • the group should be determined by the ‘d_prefix’ column value of a row immediately after non-Nan ‘d_header’ row

So in the following example:

  • 0: ‘d_header’ == ‘##### MOROCCO #####’
  • 1: check ‘d_prefix’ and set ‘d_header’ column for all rows going forward to ‘##### MOROCCO #####’ until ‘d_prefix’ has changed (set value to NaN) OR new ‘d_header’ found (start over)
    d_title    d_prefix                            d_header d_country d_subtitles  d_season  d_episode
0        NaN        NaN                 ##### MOROCCO #####   Morocco         NaN       NaN        NaN
1     title1         AR                 ##### MOROCCO #####       NaN         NaN       NaN        NaN
2     title2         AR                 ##### MOROCCO #####       NaN         NaN       NaN        NaN
3        NaN        NaN             ##### MOROCCO TNT #####   Morocco         NaN       NaN        NaN
4     title3         AR             ##### MOROCCO TNT #####       NaN         NaN       NaN        NaN
5        NaN        NaN                 ##### ALGERIA #####   Algeria         NaN       NaN        NaN
6     title4         AR                 ##### ALGERIA #####       NaN         NaN       NaN        NaN
7     title5         AR                 ##### ALGERIA #####       NaN         NaN       NaN        NaN
8     title6         IT                                 NaN       NaN         NaN       NaN        NaN
9     title7         PL                                 NaN       NaN         NaN       1.0        1.0
10    title8         UK                                 NaN       NaN         NaN       NaN        NaN
11    title9         UK                                 NaN       NaN         NaN       NaN        NaN

but I’m not having any luck with this approach. Would there be a better way to achieve the same result?

Advertisement

Answer

  • d_prefix is almost the grouping key you need. bfill it then groupby()
  • reduced to simple ffill
df = df.assign(d_header=df.assign(t_prefix=df.d_prefix.fillna(method="bfill"))
 .groupby("t_prefix", as_index=False).apply(lambda dfa: dfa.d_header.fillna(method="ffill"))
 .reset_index(drop=True)
)

d_title d_prefix d_header d_country d_subtitles d_season d_episode
0 nan nan ##### MOROCCO ##### Morocco nan nan nan
1 title1 AR ##### MOROCCO ##### nan nan nan nan
2 title2 AR ##### MOROCCO ##### nan nan nan nan
3 nan nan ##### MOROCCO 2 ##### Morocco nan nan nan
4 title3 AR ##### MOROCCO 2 ##### nan nan nan nan
5 nan nan ##### ALGERIA ##### Algeria nan nan nan
6 title4 AR ##### ALGERIA ##### nan nan nan nan
7 title5 AR ##### ALGERIA ##### nan nan nan nan
8 title6 IT nan nan nan nan nan
9 title7 PL nan nan nan 1 1
10 title8 UK nan nan nan nan nan
11 title9 UK nan nan nan nan nan
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement