Python中分组聚合指定列并保留其他列的可行方案
Got it, let's work through this problem with your corrected dataset. Looking at your data, each group (defined by colA + colB) has consistent, unique values for colC and colE—even the None in the last group. So we can solve this with a single, efficient groupby aggregation without needing extra joins or messy workarounds.
最优方案:精准指定聚合规则
Use groupby.agg() to define exactly what to do with each column. Since colC and colE have unique values per group, we can just grab the first occurrence (which is faster than deduplication), while summing colD.
完整代码示例
import pandas as pd # 你的修正后数据集 data = [ ["25-5-19", "cat1", "cat3", 10, 1], ["25-5-19", "cat1", "cat3", 20, 1], ["25-5-19", "cat1", "cat3", 30, 1], ["26-5-19", "cat2", "cat4", 50, 2], ["26-5-19", "cat2", "cat4", 100, 2], ["26-5-19", "cat2", "cat4", 10, 2], ["27-5-19", "cat1", "cat5", 40, None], ["27-5-19", "cat1", "cat5", 60, None] ] df = pd.DataFrame(data, columns=["colA", "colB", "colC", "colD", "colE"]) # 分组聚合:一次操作完成 result = df.groupby(['colA', 'colB'], as_index=False).agg( colC=('colC', 'first'), # 每个分组内colC唯一,取第一个即可 colD_sum=('colD', 'sum'), # 对colD求和 colE=('colE', 'first') # 保留colE的唯一值,包括None ) print(result)
输出结果
colA colB colC colD_sum colE 0 25-5-19 cat1 cat3 60 1.0 1 26-5-19 cat2 cat4 160 2.0 2 27-5-19 cat1 cat5 100 NaN
(注:Pandas默认会将Python的None转为NaN,但这会正确保留缺失值的语义)
为什么你之前的方法有问题?
Let's break down the issues with your initial attempts:
- 方法1: 你只指定了
colC的聚合规则——只需要在agg字典里加上colE的处理,就能把它包含到结果里。 - 方法2: 聚合后关联原表效率很低,尤其是面对100+变量的数据集时,会带来不必要的内存开销和处理时间。
- 方法3: 将所有列加入分组不符合需求,因为你需要对
colD求和(合并行),而不是按每一列分组。另外,虽然新版Pandas支持对NaN/None分组,但这种方式会保留所有原始行,无法实现colD的求和目标。
备选方案:Transform + 去重(适合特殊场景)
如果你因为某些原因需要保留原始行结构,可以用transform()给每一行添加上分组后的colD求和值,再去重:
df['colD_sum'] = df.groupby(['colA', 'colB'])['colD'].transform('sum') result = df[['colA', 'colB', 'colC', 'colD_sum', 'colE']].drop_duplicates()
但这种方法在大数据集上的效率不如直接聚合的方案。
内容的提问来源于stack exchange,提问作者Shoaibkhanz

