R中group_by %>% summarise的Pandas等效实现方法问询
实现与dplyr等效的Pandas分组聚合操作
针对你想要把R的dplyr分组聚合逻辑转成Pandas的需求,确实groupby().agg()在处理这类需要跨列依赖的聚合时不够灵活,我们可以用groupby.apply()来实现完全一致的逻辑,下面是具体步骤:
1. 重现测试数据
首先生成你提供的测试DataFrame:
import pandas as pd import numpy as np size = 20 np.random.seed(456) df = pd.DataFrame({ "names": np.random.choice(["bob", "alb", "jr"], size=size, replace=True), "income": np.random.normal(size=size, loc=1000, scale=100), "costs": np.random.normal(size=size, loc=500, scale=100), "date": np.random.choice(pd.date_range("2018-01-01", "2018-01-06"), size=size, replace=True) })
2. 自定义分组聚合函数
写一个函数接收每个分组的子DataFrame,完全复刻你R中的计算逻辑:
def calculate_group_metrics(group): # 计算总收入、总成本和净收入 income_acc = group['income'].sum() costs_acc = group['costs'].sum() net = income_acc - costs_acc # 获取分组内的最大日期,筛选对应行计算总和 max_group_date = group['date'].max() filtered_rows = group[group['date'] == max_group_date] income_acc_bymax = filtered_rows['income'].sum() cost_acc_bymax = filtered_rows['costs'].sum() # 计算growth指标 growth = income_acc_bymax + cost_acc_bymax - net # 返回聚合结果,用Series保证列名对应 return pd.Series({ 'income_acc': income_acc, 'costs_acc': costs_acc, 'net': net, 'income_acc_bymax': income_acc_bymax, 'cost_acc_bymax': cost_acc_bymax, 'growth': growth })
3. 执行分组聚合并查看结果
将自定义函数应用到分组上,用reset_index()把分组列还原为普通列:
dfg = df.groupby('names').apply(calculate_group_metrics).reset_index() print(dfg)
输出结果和你R中的结果完全一致:
names income_acc costs_acc net income_acc_bymax cost_acc_bymax growth 0 alb 7997.466538 3996.053670 4001.412868 2997.855009 1500.876851 497.318992 1 bob 6003.488978 3003.540598 2999.948380 2001.533870 1002.151162 3.736652 2 jr 6002.056904 3000.346010 3001.710894 999.833162 499.328510 -1502.549221
为什么不用agg()?
groupby().agg()更适合对单一列执行简单聚合(比如求和、均值),但当你的聚合逻辑需要依赖同组内其他列的计算结果(比如先找分组最大日期,再用该日期筛选行求和),apply()可以直接操作整个分组的子DataFrame,灵活性更高,逻辑也和你R中的dplyr代码更匹配。
内容的提问来源于stack exchange,提问作者erickfis
相关产品推荐
相关产品推荐

