如何按sales_rep分组,对满足日期区间匹配条件的amount求和
Pandas 自定义分组求和实现方案
前置处理
首先需要将日期字段转换为 datetime 类型,避免字符串比较出现逻辑错误:
import pandas as pd # 转换日期列格式 df['open_date'] = pd.to_datetime(df['open_date']) df['close_date'] = pd.to_datetime(df['close_date'])
实现方式1:分组逐行计算(易读,适合中小数据量)
按销售人员分组后,逐行匹配符合条件的记录求和,逻辑直观易修改:
def calc_open_amount_sum(group): result = [] for _, current_row in group.iterrows(): current_close = current_row['close_date'] # 筛选组内满足「其他行open日期 <= 当前行close日期 <= 其他行close日期」的记录 filter_mask = (group['open_date'] <= current_close) & (group['close_date'] >= current_close) result.append(group.loc[filter_mask, 'amount'].sum()) group['open_amount_sum'] = result return group df = df.groupby('sales_rep', group_keys=False).apply(calc_open_amount_sum)
实现方式2:自连接聚合(高性能,适合大数据量)
如果数据量较大逐行遍历效率低,可以用自连接+过滤聚合的方式减少循环开销:
# 生成分组内行号用于关联匹配 df['row_id'] = df.groupby('sales_rep').cumcount() # 同组内自连接 cartesian_df = df.merge( df[['sales_rep', 'row_id', 'open_date', 'close_date', 'amount']], on='sales_rep', suffixes=('', '_match') ) # 过滤符合条件的匹配行 filter_mask = (cartesian_df['open_date_match'] <= cartesian_df['close_date']) & (cartesian_df['close_date_match'] >= cartesian_df['close_date']) # 按原行分组求和 sum_result = cartesian_df[filter_mask].groupby(['sales_rep', 'row_id'])['amount_match'].sum().rename('open_amount_sum').reset_index() # 结果合并回原表 df = df.merge(sum_result, on=['sales_rep', 'row_id']).drop('row_id', axis=1)
如果业务场景中存在日期空值,可以在过滤条件中补充空值判断逻辑适配需求
内容的提问来源于stack exchange,提问作者Patelra95
相关产品推荐
相关产品推荐

