将group by后列的多个值合并到python中的一列中
我希望完成与此线程类似的任务: 但不同之处在于,我希望创建一个新列,该列在按另一列分组后合并一列中的所有非空值。以下是一个玩具示例:将group by后列的多个值合并到python中的一列中,python,pandas,dataframe,row,pandas-groupby,Python,Pandas,Dataframe,Row,Pandas Groupby,我希望完成与此线程类似的任务: 但不同之处在于,我希望创建一个新列,该列在按另一列分组后合并一列中的所有非空值。以下是一个玩具示例: df= pd.DataFrame({'ID1' : [1,1,2,2,3,3,3],'ID2' : ['a','a','b','b','c','c','c'], 'Status' : pd.Series([np.nan,'1', np.nan,'1','2',np.nan,'1'],
df= pd.DataFrame({'ID1' : [1,1,2,2,3,3,3],'ID2' : ['a','a','b','b','c','c','c'],
'Status' : pd.Series([np.nan,'1', np.nan,'1','2',np.nan,'1'],
dtype="category")})
df
Out[74]:
ID1 ID2 Status
0 1 a NaN
1 1 a 1
2 2 b NaN
3 2 b 1
4 3 c 2
5 3 c NaN
6 3 c 1
然后我想通过groupby
ID1
和ID2
:
gr = df.groupby(['ID1','ID2'])
然后,我希望我的结果如下所示:
Out:
NewCol
0 1
1 1
2 2,1
因此,它是一个新的DataFrame
,包含Status
列的non-null
值,按ID1
和ID2
分组
提前感谢。使用lambda函数是最通用的解决方案:
df1 = df.groupby(['ID1','ID2'])['Status'].agg(lambda x: ','.join(x.dropna())).reset_index()
print (df1)
ID1 ID2 Status
0 1 a 1
1 2 b 1
2 3 c 2,1
df1 = df.groupby(['ID1','ID2'])['Status'].agg(lambda x: ','.join(x.dropna())).reset_index()
print (df1)
ID1 ID2 Status
0 1 a
1 2 b 1
2 3 c 2,1
另一个想法是在第一步中删除重复项,但如果某个组的值仅为mising,则该组将从输出中删除,因此有必要进行下一步处理,如合并
:
#first group with only NaNs
df= pd.DataFrame({'ID1' : [1,1,2,2,3,3,3],'ID2' : ['a','a','b','b','c','c','c'],
'Status' : pd.Series([np.nan,np.nan, np.nan,'1','2',np.nan,'1'],
dtype="category")})
#first group is dropped
df11 = (df.dropna(subset=['Status'])
.groupby(['ID1','ID2'])['Status']
.agg(','.join)
.reset_index())
print (df11)
ID1 ID2 Status
0 2 b 1
1 3 c 2,1
#added missing pairs and `NaN`s converted to empty strings:
df2 = df.drop_duplicates(['ID1','ID2'])[['ID1','ID2']].merge(df11, how='left').fillna('')
print (df2)
ID1 ID2 Status
0 1 a
1 2 b 1
2 3 c 2,1
第一个解决方案:
df1 = df.groupby(['ID1','ID2'])['Status'].agg(lambda x: ','.join(x.dropna())).reset_index()
print (df1)
ID1 ID2 Status
0 1 a 1
1 2 b 1
2 3 c 2,1
df1 = df.groupby(['ID1','ID2'])['Status'].agg(lambda x: ','.join(x.dropna())).reset_index()
print (df1)
ID1 ID2 Status
0 1 a
1 2 b 1
2 3 c 2,1
是的,没错。谢谢。