Python:Groupby First Non NaN Value

时间:2018-02-04 22:08:32

标签: python pandas

我有以下数据框:

id    number   
1      13
1      13
1      NaN
1      NaN
2      11
2      11
2      11
2      NaN

我想找到每个id的第一个非NaN值,并用1标记它。结果应如下所示:

id    number     code   
1      13         NaN
1      13         1
1      NaN        NaN
1      NaN        NaN
2      11         NaN
2      11         NaN
2      11         1
2      NaN        NaN

我尝试了以下命令,然后从那里开始:

df["test"] = df.groupby("id")["number"].first_valid_index()

它给出了以下错误:无法访问'SeriesGroupBy'对象的可调用属性'first_valid_index',尝试使用'apply'方法

然后我尝试了这个:

df['test'] = df.groupby("id")['number'].apply(lambda x: x.first_valid_index())

但这只给了我一栏Nats ......

有人知道如何有效解决问题吗?

2 个答案:

答案 0 :(得分:4)

假设您的意思是last_valid_index,您可以apply last_valid_index功能和loc分配 -

df.loc[df.groupby('id').number.apply(pd.Series.last_valid_index), 'code'] = 1
df

   id  number  code
0   1    13.0   NaN
1   1    13.0   1.0
2   1     NaN   NaN
3   1     NaN   NaN
4   2    11.0   NaN
5   2    11.0   NaN
6   2    11.0   1.0
7   2     NaN   NaN

或者,使用groupby + idxmax -

df.loc[df.number.notnull().cumsum().groupby(df.id).idxmax(), 'code'] = 1
df

   id  number  code
0   1    13.0   NaN
1   1    13.0   1.0
2   1     NaN   NaN
3   1     NaN   NaN
4   2    11.0   NaN
5   2    11.0   NaN
6   2    11.0   1.0
7   2     NaN   NaN

答案 1 :(得分:2)

您可以使用此...

df.loc[df.groupby('id').apply(lambda x : x['number'].dropna()).reset_index(level=1)['level_1'].max(level=0),'code']=1
df
Out[628]: 
   id  number  code
0   1    13.0   NaN
1   1    13.0   1.0
2   1     NaN   NaN
3   1     NaN   NaN
4   2    11.0   NaN
5   2    11.0   NaN
6   2    11.0   1.0
7   2     NaN   NaN