如何在Pandas中按组选择不同聚合函数实现分组聚合?
问题描述
我需要在Pandas中执行分组聚合操作,但希望为每个分组使用特殊列(存储所需聚合函数)指定的函数。以下示例更易说明:
| id | group | val | func |
|---|---|---|---|
| 0 | 0 | 0 | "avg" |
| 1 | 0 | 2 | "avg" |
| 2 | 0 | 2 | "avg" |
| 3 | 1 | 0 | "med" |
| 4 | 1 | 2 | "med" |
在该示例中,预期对group 0执行"avg"(平均值)聚合,对group 1执行"med"(中位数)聚合。如何让agg方法根据"func"列的值选择对应函数?我知道可以为每个分组计算所有聚合函数再筛选,但会产生大量不必要计算,应有更优方案...
注:已确保每个分组内的func值一致,无需处理冲突情况。
解决方案
通过分组后自定义函数apply可实现按需聚合,避免冗余计算,具体操作如下:
- 定义函数名称映射字典,将业务侧的函数名转换为Pandas支持的标准聚合函数名:
func_dict = {"avg": "mean", "med": "median", "min": "min", "max": "max", "rnk": "first"}
- 编写自定义聚合函数,接收分组后的子DataFrame,根据分组内指定的函数执行对应操作:
def pick_price(subframe: pd.DataFrame) -> float: func_name = subframe["agg"].iloc[0] func_name = func_dict[func_name] # 从分组首行获取函数名并转换为Pandas标准名称 if func_name != "first": ans = subframe["comp_price"].agg(func_name) return 1.0 * ans else: # 针对"rnk"对应的"first"逻辑,取rank最小的行对应的comp_price idx = subframe["rank"].idxmin() return 1.0 * subframe["comp_price"].loc[idx]
- 执行分组聚合:先按目标列分组,再通过
apply调用自定义函数:
grouped = X.groupby("sku") grouped.apply(pick_price)
内容的提问来源于stack exchange,提问作者Igor Agafonov
相关产品推荐
相关产品推荐

