Pandas GroupBy如何使用单次计算双值的自定义聚合函数?
核心诉求
使用单个可同时返回多值的自定义聚合函数,对分组后的DataFrame完成计算,最终生成列方向的多级索引结构(第一级为原列名,第二级为自定义函数返回的聚合标签),和df.groupby('A').agg([min, max])的输出结构完全一致,避免行方向多级索引、双重嵌套apply的低效写法。
实现方案
方案1:单层级apply匹配目标列结构
将原先嵌套在两层apply内部的逐列聚合逻辑,封装为分组处理函数,单层级调用即可拿到目标结构:
def process_group(g): # 剔除分组列后,对所有数值列调用自定义minmax函数 res = g.drop(columns='A').apply( lambda col: pd.Series( minmax(col), index=['min', 'max'] ) ) # 转置后形成(原列名, 聚合标签)的列层级结构 return res.T result = df.groupby('A').apply(process_group)
输出结果和预期完全一致:
B C min max min max A 1 1 3 4 6 2 4 6 7 9
方案2:命名聚合适配自定义函数
如果使用pandas 0.25及以上版本,可以借助命名聚合能力,基于自定义函数拆分独立的聚合列,再调整为多级列结构:
# 基于自定义minmax函数,拆出两个独立的取值逻辑 def get_min(col): return minmax(col)[0] def get_max(col): return minmax(col)[1] result = df.groupby('A').agg( B_min=('B', get_min), B_max=('B', get_max), C_min=('C', get_min), C_max=('C', get_max) ) # 将扁平列名调整为和示例一致的多级列结构 result.columns = pd.MultiIndex.from_tuples([ (col.split('_')[0], col.split('_')[1]) for col in result.columns ])
这种方式的灵活性更高,可以根据自定义函数返回的任意数量的值,自由定义聚合列的标签,不受固定min/max命名的限制。
方案3:多列批量计算优化性能
如果自定义函数支持一次性对多列计算返回结果,可以直接将逐列循环的逻辑封装进自定义函数内部,减少apply的遍历开销:
def minmax_multi(cols): # 一次性输入整个分组的数值列,批量计算每列的min、max return pd.DataFrame( {col: minmax(cols[col]) for col in cols.columns}, index=['min', 'max'] ).T result = df.groupby('A').apply( lambda g: minmax_multi(g.drop(columns='A')) )
内容的提问来源于stack exchange,提问作者a_guest
相关产品推荐
相关产品推荐

