【问题标题】:How can I aggregate a dataframe on specific values?如何聚合特定值的数据框?
【发布时间】:2019-01-09 07:27:46
【问题描述】:

我有一个像这样的pandas 数据框df,比如说

ID activity date
1  A        4
1  B        8
1  A        12
1  C        12
2  B        9
2  A        10
3  A        3
3  D        4

我想返回一个表格,在一个精确的列表中计算某些activity 的出现次数,在这种情况下说l = [A, B],然后

ID activity(count)_A  activity(count)_B
1  2                  1
2  1                  2
3  1                  0

是我需要的。

最快的方法是什么?理想情况下没有for 循环

谢谢!

编辑:我知道有pivot 函数可以做这种工作。但就我而言,activity 类型比我真正需要在列表l 中计数的类型要多得多。使用pivot 仍然是最佳选择吗?

【问题讨论】:

    标签: python pandas pandas-groupby pandas-apply


    【解决方案1】:

    您可以使用isinboolean indexing 作为第一步,然后旋转 - 最快的应该是groupbysizeunstack,然后是pivot_table,最后是crosstab,这是每个解决方案的最佳测试真实数据:

    df2 = (df[df['activity'].isin(['A','B'])]
             .groupby(['ID','activity'])
             .size()
             .unstack(fill_value=0)
             .add_prefix('activity(count)_')
             .reset_index()
             .rename_axis(None, axis=1))
    
    print (df2)
       ID  activity(count)_A  activity(count)_B
    0   1                  2                  1
    1   2                  1                  1
    2   3                  1                  0
    

    或者:

    df1 = df[df['activity'].isin(['A','B'])]
    
    df2 = (pd.crosstab(df1['ID'], df1['activity'])
            .add_prefix('activity(count)_')
            .reset_index()
            .rename_axis(None, axis=1))
    

    或者:

    df2 = (df[df['activity'].isin(['A','B'])]
              .pivot_table(index='ID', columns='activity', aggfunc='size', fill_value=0)
              .add_prefix('activity(count)_')
              .reset_index()
              .rename_axis(None, axis=1))
    

    【讨论】:

      【解决方案2】:

      我相信df.groupby('activity').size().reset_index(name='count') 应该如你所愿。

      【讨论】:

        【解决方案3】:

        只需按Counter 聚合并使用pd.DataFrame 默认构造函数

        from collections import Counter
        
        agg_= df.groupby(df.index).ID.agg(Counter).tolist()
        ndf = pd.DataFrame(agg_)
        
            A   B   C   D
        0   2   1.0 1.0 NaN
        1   1   1.0 NaN NaN
        2   1   NaN NaN 1.0
        

        如果你有l = ['A', 'B'],只需过滤

        ndf[l]
        
            A   B   
        0   2   1.0 
        1   1   1.0 
        2   1   NaN
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-02-26
          • 1970-01-01
          • 1970-01-01
          • 2021-06-01
          • 1970-01-01
          • 2020-08-14
          • 2018-11-11
          • 2017-03-26
          相关资源
          最近更新 更多