You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 07:09:02