基于Groupby分组按条件对DataFrame行求和的实现方法
实现自定义分组求和的高效方法
原始DataFrame
| A | B | Percent | Groupby |
|---|---|---|---|
| 2 | 0 | 10 | All |
| 2 | 1 | 5 | All |
| 2 | 2 | 6 | All |
| 2 | 0 | 20 | Type A |
| 2 | 1 | 15 | Type A |
| 2 | 2 | 8 | Type A |
| 3 | 0 | 10 | All |
| 3 | 1 | 5 | All |
| 3 | 2 | 6 | All |
| 3 | 3 | 3 | All |
| 3 | 0 | 20 | Type A |
| 3 | 1 | 15 | Type A |
| 3 | 2 | 8 | Type A |
| 3 | 3 | 11 | Type A |
| 4 | 0 | 10 | All |
| 4 | 1 | 5 | All |
| 4 | 2 | 6 | All |
| 4 | 3 | 3 | All |
| 4 | 4 | 1 | All |
| 4 | 0 | 20 | Type A |
| 4 | 1 | 15 | Type A |
| 4 | 2 | 8 | Type A |
| 4 | 3 | 11 | Type A |
| 4 | 4 | 2 | Type A |
期望结果
| A | B | Percent | Groupby | sum |
|---|---|---|---|---|
| 2 | 0 | 10 | All | 10 |
| 2 | 1 | 5 | All | 11 |
| 2 | 2 | 6 | All | 11 |
| 2 | 0 | 20 | Type A | 20 |
| 2 | 1 | 15 | Type A | 23 |
| 2 | 2 | 8 | Type A | 23 |
| 3 | 0 | 10 | All | 15 |
| 3 | 1 | 5 | All | 15 |
| 3 | 2 | 6 | All | 9 |
| 3 | 3 | 3 | All | 9 |
| 3 | 0 | 20 | Type A | 35 |
| 3 | 1 | 15 | Type A | 35 |
| 3 | 2 | 8 | Type A | 19 |
| 3 | 3 | 11 | Type A | 19 |
| 4 | 0 | 10 | All | 15 |
| 4 | 1 | 5 | All | 15 |
| 4 | 2 | 6 | All | 10 |
| 4 | 3 | 3 | All | 10 |
| 4 | 4 | 1 | All | 10 |
| 4 | 0 | 20 | Type A | 35 |
| 4 | 1 | 15 | Type A | 35 |
| 4 | 2 | 8 | Type A | 21 |
| 4 | 3 | 11 | Type A | 21 |
| 4 | 4 | 2 | Type A | 21 |
需求说明
按Groupby列分组后,根据A列的值对B列进行自定义分组求和:
- 当
A=2时:B=0单独一组,B=1、2为一组,对每组的Percent求和 - 当
A=3时:B=0、1为一组,B=2、3为一组,对每组的Percent求和 - 当
A=4时:B=0、1为一组,B=2、3、4为一组,对每组的Percent求和
高效实现方案
利用Pandas的分组映射与合并功能,可快速完成需求,代码如下:
import pandas as pd # 构造原始DataFrame data = [ [2,0,10,"All"],[2,1,5,"All"],[2,2,6,"All"], [2,0,20,"Type A"],[2,1,15,"Type A"],[2,2,8,"Type A"], [3,0,10,"All"],[3,1,5,"All"],[3,2,6,"All"],[3,3,3,"All"], [3,0,20,"Type A"],[3,1,15,"Type A"],[3,2,8,"Type A"],[3,3,11,"Type A"], [4,0,10,"All"],[4,1,5,"All"],[4,2,6,"All"],[4,3,3,"All"],[4,4,1,"All"], [4,0,20,"Type A"],[4,1,15,"Type A"],[4,2,8,"Type A"],[4,3,11,"Type A"],[4,4,2,"Type A"] ] df = pd.DataFrame(data, columns=["A","B","Percent","Groupby"]) # 定义分组规则:key为A的值,value为B到分组标签的映射 group_mapping = { 2: {0: "group_0", 1: "group_1_2", 2: "group_1_2"}, 3: {0: "group_0_1", 1: "group_0_1", 2: "group_2_3", 3: "group_2_3"}, 4: {0: "group_0_1", 1: "group_0_1", 2: "group_2_3_4", 3: "group_2_3_4", 4: "group_2_3_4"} } # 给每行添加分组标签 df["group_tag"] = df.apply(lambda row: group_mapping[row["A"]][row["B"]], axis=1) # 按Groupby、A、分组标签求和 sum_df = df.groupby(["Groupby", "A", "group_tag"])["Percent"].sum().reset_index(name="sum") # 合并求和结果到原始DataFrame,删除临时标签列 result_df = df.merge(sum_df, on=["Groupby", "A", "group_tag"], how="left").drop("group_tag", axis=1) # 输出结果 print(result_df)
方案说明
- 分组映射定义:通过字典明确每个
A值对应的B分组逻辑,将同一组的B值映射到统一标签,避免重复判断 - 添加分组标签:用
apply为每行匹配对应的分组标签,为后续分组求和做准备 - 分组求和:按
Groupby、A、分组标签对Percent列求和,得到每组的总和 - 合并结果:将求和结果关联回原始DataFrame,删除临时标签列后得到最终结果
该方案利用Pandas的向量化操作,相比循环处理效率更高,且逻辑清晰易维护。
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

