【问题标题】:Merge multiple values of a column after group by into one column in python pandas将分组后列的多个值合并为python pandas中的一列
【发布时间】:2020-07-02 09:10:56
【问题描述】:

我正在寻找与此线程中类似的任务:Merge multiple column values into one column in python pandas

但不同的是,我想创建一个新列,在按另一列分组后合并一列中的所有非空值。这是一个玩具示例:

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

然后我想groupbyID1ID2

gr = df.groupby(['ID1','ID2'])

然后,我希望我的结果如下所示:

Out:
   NewCol
0   1
1   1
2   2,1

所以它是一个新的DataFrame,其中包含Status 列的non-null 值,该列按ID1ID2 分组。

提前致谢。

【问题讨论】:

    标签: python pandas dataframe row pandas-groupby


    【解决方案1】:

    使用 GroupBy.agg 和 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
    

    另一个想法是在第一步中删除重复的,但是如果某个组只有错误值,它会从输出中删除,所以接下来的处理是必要的,比如merge

    #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    2   b      1
    2    3   c    2,1
    

    【讨论】:

    • 是的,完全正确。非常感谢。
    猜你喜欢
    • 2016-01-10
    • 1970-01-01
    • 1970-01-01
    • 2016-09-22
    • 2017-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多