【问题标题】:Aggregate up to current row without loops in Pandas在 Pandas 中聚合到没有循环的当前行
【发布时间】:2020-03-12 05:12:03
【问题描述】:

我有一个包含ideventmetric 列的数据集:

df = pd.DataFrame([['a','x', 1], 
                  ['a','x',2],  
                  ['b','y',3],  
                  ['a','z',4],  
                  ['a','j',5]], columns = ['id','event','metric'])

   id event metric
0   a   x   1
1   a   x   2
2   b   y   3
3   a   z   4
4   a   j   5

我需要将它按 idevent 分组以得到 summeanstdminmax metric 的聚合,这不仅包括 a给定“id-event”组,但对于给定的id所有以前的事件metric 值。换句话说,我需要聚合所有行,直到给定行。

期望的输出:

   id event sum mean        std       min   max
0   a   j   12  3.000000    1.825742    1   5
1   a   x   3   1.500000    0.707107    1   2
2   a   z   7   2.333333    1.527525    1   4
3   b   y   3   3.000000    NaN         3   3

当我刚刚为每个组过滤我的数据框时,我尝试了 for-loop 方法。但问题是我有大约 20M 行,所以计算需要很长时间。我正在尝试解决这个无循环

【问题讨论】:

    标签: python pandas aggregation


    【解决方案1】:

    您需要使用groupby

    df.groupby(["id", "event"])["metric"].describe()
    

    【讨论】:

    • 不幸的是,这只会给我每个“id”、“event”的聚合值。棘手的部分是我还需要汇总此事件之前的所有指标值。所以我认为 Groupby 并没有解决问题(至少在这种基本形式中)。
    【解决方案2】:

    您需要sort_values on id 和选项quicksort 才能在id 上排序,但在其他列上保持原始顺序。接下来,groupbyid 上和expandingsum, mean, std, min, max 上。最后,pd.concatevent 列添加到最终 df。 drop_duplicates 只保留每组的最后一行 id-eventsort_values 以获得您想要的顺序。

    df1 = df.sort_values('id', kind='quicksort')
    df2 = df1.groupby('id').expanding().metric.agg(['sum', 'mean', 'std', 'min', 'max']).droplevel(1)
    df_final = (pd.concat([df1.set_index('id').event, df2], axis=1).reset_index().
                  drop_duplicates(subset=['id', 'event'], keep='last').
                  sort_values(['id', 'event']))
    
    Out[96]:
      id event   sum      mean       std  min  max
    3  a     j  12.0  3.000000  1.825742  1.0  5.0
    1  a     x   3.0  1.500000  0.707107  1.0  2.0
    2  a     z   7.0  2.333333  1.527525  1.0  4.0
    4  b     y   3.0  3.000000       NaN  3.0  3.0
    

    【讨论】:

    • 结果是完美的,除了“a-x”组。为什么那里是4?应该是 3,对吧?
    • 另外,这不适用于其他聚合。例如。对于 aj 组的平均值 (df.groupby('id').cumsum().groupby([t.id, t.event]).metric.mean().reset_index()) 它给出 12。应该是 (1 +2+4+5)/4=3
    • 您能否为meanminmaxstd 的其余部分发布所需的输出?
    • 我添加了完整的所需输出
    猜你喜欢
    • 2023-01-18
    • 2019-08-11
    • 2019-07-16
    • 1970-01-01
    • 1970-01-01
    • 2022-12-28
    • 1970-01-01
    • 2018-04-16
    • 1970-01-01
    相关资源
    最近更新 更多