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

如何在Pandas中按ID和CD的连续变化分组并获取起止日期?

解决按ID+连续CD分组并获取起止日期的问题

问题需求

需要按ID分组,同时根据CD列的连续相同值划分独立小组,获取每个连续小组的起始日期和结束日期。原方法直接按ID和CD分组会将同一ID下非连续的同CD记录合并,无法满足需求。

原始数据集

import pandas as pd
import numpy as np

df = pd.DataFrame({'ID': [1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2],
 'DATE': ['1/1/2015','1/2/2015', '1/3/2015','1/4/2015','1/5/2015','1/6/2015','1/7/2015','1/8/2015',
  '1/9/2016','1/2/2015','1/3/2015','1/4/2015','1/5/2015','1/6/2015','1/7/2015'],
 'CD': ['A','A','A','A','B','B','A','A','C','A','A','A','A','A','A']})

原方法的问题

原代码通过df.groupby(['ID','CD']).agg(...)分组时,会将同一ID下所有同CD的记录归为一组,例如ID=1中,1/1-1/4的A和1/7-1/8的A会被合并,忽略了中间的B,无法区分连续的CD分组。

正确解决方案

核心思路是创建一个连续分组标识,对每个ID,当CD值发生变化时,分组标识递增,以此区分非连续的同CD小组。

步骤1:转换日期格式

将DATE列转换为日期类型,确保后续能正确计算最小/最大值:

df['DATE'] = pd.to_datetime(df['DATE'])

步骤2:生成连续分组标识

# 对每个ID,判断当前行CD是否与上一行不同,生成布尔值后累加得到唯一分组ID
df['group_id'] = df.groupby('ID')['CD'].apply(lambda x: x.ne(x.shift()).cumsum())

步骤3:分组聚合起止日期

按ID、CD和group_id分组,聚合每个小组的起始和结束日期,最后移除辅助列:

result = df.groupby(['ID', 'CD', 'group_id']).agg(
    Start_Date=('DATE', 'min'),
    End_Date=('DATE', 'max')
).reset_index().drop(columns='group_id')

最终结果

ID CD Start_Date  End_Date
0   1  A 2015-01-01 2015-01-04
1   1  B 2015-01-05 2015-01-06
2   1  A 2015-01-07 2015-01-08
3   1  C 2016-01-09 2016-01-09
4   2  A 2015-01-02 2015-01-07

内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 13:30:47