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

如何在Python Pandas DataFrame中识别最新连续相同值序列

问题描述

我有一个包含Id和Date(格式为dd-mm-yyyy)的Pandas DataFrame,创建代码如下:

import pandas as pd
data={'Id':['A', 'B', 'C', 'A', 'B', 'C', 'B', 'C', 'A', 'C', 'B', 'C', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C'],
  'Date':['20-10-2022', '20-10-2022', '20-10-2022', '21-10-2022', '21-10-2022', '21-10-2022',
          '22-10-2022', '22-10-2022', '23-10-2022', '23-10-2022', '24-10-2022', '24-10-2022',
          '25-10-2022', '25-10-2022', '26-10-2022', '26-10-2022', '26-10-2022', '27-10-2022',
          '27-10-2022', '27-10-2022']}
df=pd.DataFrame.from_dict(data)

对应的DataFrame内容:

Id        Date
0   A  20-10-2022
1   B  20-10-2022
2   C  20-10-2022
3   A  21-10-2022
4   B  21-10-2022
5   C  21-10-2022
6   B  22-10-2022
7   C  22-10-2022
8   A  23-10-2022
9   C  23-10-2022
10  B  24-10-2022
11  C  24-10-2022
12  B  25-10-2022
13  C  25-10-2022
14  A  26-10-2022
15  B  26-10-2022
16  C  26-10-2022
17  A  27-10-2022
18  B  27-10-2022
19  C  27-10-2022

我需要得到每个Id的最新连续出现序列对应的起止日期,但尝试的代码只能得到每个Id的首次和末次出现日期:

# 查找每个Id的首次和末次出现
df_first_duplicate = df.drop_duplicates(subset=['Id'], keep='first')
df_first_duplicate.rename(columns = {'Date':'DateOfFirstOccurance'}, inplace = True)
df_first_duplicate.reset_index(inplace = True, drop = True)
df_last_duplicate = df.drop_duplicates(subset=['Id'], keep='last')
df_last_duplicate.rename(columns = {'Date':'DateOfLastOccurance'}, inplace = True)
df_last_duplicate.reset_index(inplace = True, drop = True)
# 合并两个结果
df_merged = pd.merge(df_first_duplicate, df_last_duplicate, on='Id')

得到的输出:

Id DateOfFirstOccurance DateOfLastOccurance
0  A           20-10-2022          27-10-2022
1  B           20-10-2022          27-10-2022
2  C           20-10-2022          27-10-2022

请问该如何修改代码以得到目标结果?


解决方案

核心思路是先识别每个Id的连续出现分组,再筛选出每个Id的最新分组,最后提取该分组的起止日期。具体步骤如下:

步骤1:转换日期格式

先将字符串类型的Date转为Pandas日期类型,确保能正确判断日期连续性:

df['Date'] = pd.to_datetime(df['Date'], format='%d-%m-%Y')

步骤2:标记连续序列分组

对每个Id,判断当前日期与前一个日期是否连续(间隔1天),通过累积求和生成连续序列的分组标签:

# 按Id分组,计算相邻日期的间隔是否为1天
df['is_continuous'] = df.groupby('Id')['Date'].diff().dt.days == 1
# 填充每个Id的第一条数据为True(无前置日期,默认属于第一个连续组)
df['is_continuous'] = df['is_continuous'].fillna(True)
# 生成分组ID:每次出现不连续时,分组号递增
df['group_id'] = df.groupby('Id')['is_continuous'].cumsum()

步骤3:提取最新连续组的起止日期

先计算每个分组的起止日期,再筛选出每个Id的最新分组(最大的group_id):

# 计算每个(Id, group_id)分组的起止日期
grouped = df.groupby(['Id', 'group_id']).agg(
    start_date=('Date', 'min'),
    end_date=('Date', 'max')
).reset_index()

# 获取每个Id的最新分组ID
latest_groups = grouped.groupby('Id')['group_id'].max().reset_index()
# 合并得到最新分组的起止日期
result = pd.merge(latest_groups, grouped, on=['Id', 'group_id']).drop('group_id', axis=1)

# 将日期转回原字符串格式
result['start_date'] = result['start_date'].dt.strftime('%d-%m-%Y')
result['end_date'] = result['end_date'].dt.strftime('%d-%m-%Y')

最终结果

运行上述代码后,得到的目标DataFrame如下:

Id  start_date    end_date
0  A  26-10-2022  27-10-2022
1  B  24-10-2022  27-10-2022
2  C  20-10-2022  27-10-2022

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 23:40:34