【问题标题】:Partially summing pandas columns部分求和 pandas 列
【发布时间】:2020-12-06 16:35:40
【问题描述】:

我有兴趣对以下数据框进行部分求和:

    ID  Name    A   B
1   111 foo     248 123
2   222 bar     331 94
3   111 foo     266 102
4   111 foo     217 163
5   222 bar     194 102
6   222 bar     188 89

我可以将groupbysumagg 一起使用,例如:

df = df.groupby(["ID", "Name"]).agg(sum).reset_index()

产生:

    ID  Name    A   B
1   111 foo     731 388
2   222 bar     713 285

但是,我只想在 A 列通过某个预先指定的值之前合并索引,然后开始第二次分组。当那个通过预先指定的值时,开始第三个分组,依此类推。例如,如果阈值设置为 500,则代码将产生:

    ID  Name    A   B
1   111 foo     514 225
2   222 bar     525 196
3   111 foo     217 163
4   222 bar     188 89

原始 df 中的第 1 行和第 3 行被分组。第 2 行和第 4 行被分组。第 5 行不与第 1 行和第 3 行分组,因为已超过 500 的阈值。第 6 行同样未分组。

行的顺序无关紧要。哪些行与哪些其他行结合并不重要。我只需要使用阈值对列值进行分组的能力。我很难过,尤其是在试图找出 Pythonic 解决方案而不是逐行遍历数据帧并显式评估每一行时。任何反馈将不胜感激。

【问题讨论】:

标签: python pandas dataframe


【解决方案1】:

您可以使用自定义函数传递给 apply 函数来执行此操作。 首先使用 cumsum 标识组结束,使用新的组 id 创建一个额外的列,然后在新的中间数据帧上执行另一个 groupby。

我已将阈值作为函数中的参数。

def grouper(x,threshold=500):
    A = (x['A'].cumsum().values/threshold).astype(int)
    loc = (np.diff(A)!=0).nonzero()[0]+1
    A[loc] = A[loc]-1 
    x['C'] = A
    
    return x.groupby(['C'])['A','B'].sum().reset_index(drop=True)
    
    

df.groupby(["ID", "Name"]).apply(grouper,threshold=500)

【讨论】:

  • 我不得不稍微调整一下代码,但这正是我想要的。
猜你喜欢
  • 1970-01-01
  • 2017-09-27
  • 2014-10-21
  • 1970-01-01
  • 2018-07-30
  • 1970-01-01
  • 1970-01-01
  • 2014-07-01
  • 1970-01-01
相关资源
最近更新 更多