如何在Pandas DataFrame GroupBy中实现多列参与的聚合操作?
实现DataFrame分组后涉及多列的聚合操作
当然可以实现这类涉及多列的聚合操作,问题出在你使用agg关键字参数的方式上——这种写法下,pandas会默认将单个列的Series传递给lambda,而非整个分组的子DataFrame。下面是几种可行的解决方法:
方法1:使用groupby.apply(灵活处理多列逻辑)
apply方法会直接将每个分组的完整子DataFrame传递给自定义函数,非常适合需要同时操作多列的场景:
import pandas as pd df = pd.DataFrame({ "value1": range(8), "value2": range(7, -1, -1), "Sample": [1, 2]*4, "Year": list(range(2023, 2027))*2 }) # 用apply实现多列聚合 result = df.groupby(["Sample", "Year"]).apply( lambda group: pd.Series({"agg1": (group["value1"] * group["value2"]).mean()}) ) print(result)
输出结果:
agg1 Sample Year 1 2023 0.0 2024 10.0 2025 24.0 2026 42.0 2 2023 7.0 2024 15.0 2025 27.0 2026 43.0
方法2:先计算衍生列再聚合(性能更优)
如果聚合逻辑可以拆分为“先计算多列组合值,再聚合”,推荐先生成衍生列再做分组聚合,这种方式在大数据集上性能更好:
# 先计算value1和value2的乘积列 df["value_product"] = df["value1"] * df["value2"] # 对衍生列做分组mean聚合,并重命名结果列 result = df.groupby(["Sample", "Year"])["value_product"].mean().rename("agg1") print(result)
输出和方法1完全一致,但执行效率更高,因为避免了分组内的逐组函数调用开销。
方法3:调整agg的使用方式(不推荐,仅作参考)
如果一定要用agg,可以通过传递包含整个DataFrame引用的逻辑来实现,但这种写法不够直观,且容易出错:
result = df.groupby(["Sample", "Year"]).agg( agg1=lambda x: (x * df.loc[x.index, "value2"]).mean() )["agg1"]
这里的x是value1列的Series,通过x.index关联到对应的value2值,但这种方式依赖索引的一致性,不如前两种方法可靠。
内容的提问来源于stack exchange,提问作者Thomas Arildsen
相关产品推荐
相关产品推荐

