部分汇总熊猫列

时间:2020-08-17 14:07:04

标签: python pandas dataframe

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

    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解决方案而不是逐行遍历数据帧并显式评估每一行时。任何反馈将不胜感激。

1 个答案:

答案 0 :(得分:2)

您可以使用自定义函数将其传递给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)