pandas groupby仅聚合连续分组共有ID行的高效实现方法
高性能无循环实现方案
核心思路是通过左连接匹配判断ID是否同时存在于当前日期和前一个相邻日期,全程使用pandas原生向量化操作,大数据量下性能提升明显。
基础版(适用于日期为连续整数的场景)
import pandas as pd # 示例数据 df = pd.DataFrame({ 'Date': [1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4], 'ID': [ 1, 2, 3, 4 , 2, 3, 4 , 2, 3, 4, 5, 1, 2, 3, 4], 'Value': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] }) # 拿到所有存在的(日期,ID)对,去重避免重复匹配 exists_pairs = df[['Date', 'ID']].drop_duplicates() # 生成当前日期对应的前一日期 df['prev_date'] = df['Date'] - 1 # 左连接匹配ID是否存在于前一日期 df = df.merge( exists_pairs, left_on=['prev_date', 'ID'], right_on=['Date', 'ID'], how='left', suffixes=('', '_prev') ) # 第一个日期全保留,其他日期仅保留在前一日期存在的ID min_date = df['Date'].min() keep_mask = (df['Date'] == min_date) | df['Date_prev'].notna() # 分组求和得到结果 result = df[keep_mask].groupby('Date')['Value'].sum() print(result)
运行输出和原有逻辑完全一致:
Date 1 10 2 18 3 27 4 42 Name: Value, dtype: int64
通用版(支持任意非连续日期/日期格式)
如果你的日期不是连续整数,或者是datetime类型,可先对日期做序号映射,再用相同逻辑实现:
# 给所有日期按顺序生成连续序号 date_list = df['Date'].drop_duplicates().sort_values().reset_index(drop=True) date_idx_map = {date: idx for idx, date in date_list.items()} df['date_idx'] = df['Date'].map(date_idx_map) # 后续逻辑替换为按序号匹配 exists_pairs = df[['date_idx', 'ID']].drop_duplicates() df['prev_idx'] = df['date_idx'] - 1 df = df.merge( exists_pairs, left_on=['prev_idx', 'ID'], right_on=['date_idx', 'ID'], how='left', suffixes=('', '_prev') ) keep_mask = (df['date_idx'] == 0) | df['date_idx_prev'].notna() result = df[keep_mask].groupby('Date')['Value'].sum()
内容的提问来源于stack exchange,提问作者RK1
相关产品推荐
相关产品推荐

