如何聚合特定值的数据框?

How can I aggregate a dataframe on specific values?

我有一个像这样的 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

我想 return 一个 table 来计算一些 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 仍然是最佳选择吗?

可以使用isin with boolean indexing as first step and then pivoting - fastest should be groupby, size and unstack, then pivot_table and last 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))

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

只需按 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