我有以下数据框:
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 ......
有人知道如何有效解决问题吗?
答案 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