根据pandas中的另一个Column和Row填写NaN值

The*_*odo 5 python dataframe pandas

我有这样一个DF:

Name      Food      Year_eaten      Month_eaten

Maria     Rice        2014               3
Maria     Rice        2015              NaN
Maria     Rice        2016              NaN
Jack      Steak       2011              NaN
Jack      Steak       2012               5
Jack      Steak       2013              NaN
Run Code Online (Sandbox Code Playgroud)

我希望输出看起来像这样:

Name      Food      Year_eaten      Month_eaten

Maria     Rice        2014               3
Maria     Rice        2015               3
Maria     Rice        2016               3
Jack      Steak       2011               5
Jack      Steak       2012               5
Jack      Steak       2013               5
Run Code Online (Sandbox Code Playgroud)

我想根据这个条件填写NaN:

If the row's Name, Food is the same and the Year's are consecutive:
     Fill the NaN's with the Month_eaten corresponding to the row that isn't a NaN
Run Code Online (Sandbox Code Playgroud)

将有一个人拥有所有NaN的月份食物,但我现在不需要担心.只有在任何一年中具有至少一个Month_eaten值的人.

任何想法将不胜感激!

cs9*_*s95 3

您可以对“Name”、“Food”以及通过diff“Year_eaten”行创建的自定义列进行分组。

u = df.Year_eaten.diff().bfill().ne(1).cumsum()
v = df.groupby(['Name','Food', v]).Month_eaten.transform('first')

df['Month_eaten'] = df.Month_eaten.fillna(v, downcast='infer')

df
    Name   Food  Year_eaten  Month_eaten
0  Maria   Rice        2014            3
1  Maria   Rice        2015            3
2  Maria   Rice        2016            3
3   Jack  Steak        2011            5
4   Jack  Steak        2012            5
5   Jack  Steak        2013            5
Run Code Online (Sandbox Code Playgroud)

如果没有组的所有行都包含 NaN,则另一个解决方案是使用groupbyand ffill(其他所有内容都相同)。

df['Month_eaten'] = df.groupby(['Name','Food', u]).Month_eaten.ffill().bfill()
df
    Name   Food  Year_eaten  Month_eaten
0  Maria   Rice        2014            3
1  Maria   Rice        2015            3
2  Maria   Rice        2016            3
3   Jack  Steak        2011            5
4   Jack  Steak        2012            5
5   Jack  Steak        2013            5
Run Code Online (Sandbox Code Playgroud)