问题描述
我有以下数据框:
Out[117]: mydata
author email ri oi
0 X1 NaN NaN 0000-0001-8437-498X
1 X2 NaN NaN NaN
2 X3 ab@ma.com K-5448-2012 0000-0001-8437-498X
3 X4 ab2@ma.com NaN 0000-0001-8437-498X
4 X5 ab@ma.com NaN 0000-0001-8437-498X
其中列ri
代表作者的ResearcherID,列oi
代表ORCID。一位作者可能拥有多个电子邮件地址,因此email
列中有重复项。
首先,如果ri
中的相应行共享相同的值,我尝试使用{{1}中的非NaN值来填充oi
中的na }}。我想要的结果是:
ri
第二,,如果 author email ri oi
0 X1 NaN K-5448-2012 0000-0001-8437-498X
1 X2 NaN NaN NaN
2 X3 ab@ma.com K-5448-2012 0000-0001-8437-498X
3 X4 ab2@ma.com K-5448-2012 0000-0001-8437-498X
4 X5 ab@ma.com K-5448-2012 0000-0001-8437-498X
(或email
)中的值相同,则合并电子邮件并使用合并后的值填充ri
列中的na。我想获得一个如下数据框:
oi
我尝试了以下代码:
author email ri oi
0 X1 ab@ma.com;ab2@ma.com K-5448-2012 0000-0001-8437-498X
1 X2 NaN NaN NaN
2 X3 ab@ma.com;ab2@ma.com K-5448-2012 0000-0001-8437-498X
3 X4 ab@ma.com;ab2@ma.com K-5448-2012 0000-0001-8437-498X
4 X5 ab@ma.com;ab2@ma.com K-5448-2012 0000-0001-8437-498X
此代码在第一步中返回了我想要的代码,但是是否有一种精巧的方法来解决此问题?此外,如何获取final_df = pd.DataFrame()
na_df = mydata[mydata.oi.isna()]
for i in set(mydata.oi.dropna()):
fill_df = mydata[mydata.oi == i]
fill_df.ri = fill_df.ri.fillna(method='ffill')
fill_df.ri = fill_df.ri.fillna(method='bfill')
null_df = pd.concat([null_df,fill_df])
final_df = pd.concat([final_df,na_df])
中的合并值,然后在email
的过程中将合并后的值用作输入?
解决方法
尝试2 transform
。每列一个。在ri
上,使用first
。在email
上,结合使用dropna
,unique
和join
g = df.dropna(subset=['oi']).groupby('oi')
df['ri'] = g.ri.transform('first')
df['email'] = g.email.transform(lambda x: ';'.join(x.dropna().unique()))
Out[79]:
author email ri oi
0 X1 ab@ma.com;ab2@ma.com K-5448-2012 0000-0001-8437-498X
1 X2 NaN NaN NaN
2 X3 ab@ma.com;ab2@ma.com K-5448-2012 0000-0001-8437-498X
3 X4 ab@ma.com;ab2@ma.com K-5448-2012 0000-0001-8437-498X
4 X5 ab@ma.com;ab2@ma.com K-5448-2012 0000-0001-8437-498X