如何用Pandas按日期间隔阈值分组连续行块?
按日期间隔划分DataFrame块并聚合内容
需求说明
需要将Pandas DataFrame中连续行日期间隔超过365天的部分划分为独立块,最终输出每个块的最小日期、最大日期,以及块内Data字段的合并结果。
示例输入
| Date | Data |
|---|---|
| 2019-01-01 | A |
| 2019-05-01 | B |
| 2020-04-01 | C |
| 2021-07-01 | D |
| 2022-02-01 | E |
| 2024-05-01 | F |
期望输出
| Min Date | Max Date | Data |
|---|---|---|
| 2019-01-01 | 2020-04-01 | ABC |
| 2021-07-01 | 2022-02-01 | DE |
| 2024-05-01 | 2024-05-01 | F |
解决方法
你之前尝试的diff()和cumsum()思路是可行的,问题大概率出在日期类型转换或分组标记的逻辑细节上,以下是完整可运行的实现步骤:
步骤1:转换日期类型并计算间隔
首先确保Date列是datetime格式,才能正确计算日期间隔:
import pandas as pd # 构造示例数据 df = pd.DataFrame({ 'Date': ['2019-01-01', '2019-05-01', '2020-04-01', '2021-07-01', '2022-02-01', '2024-05-01'], 'Data': ['A', 'B', 'C', 'D', 'E', 'F'] }) # 转换为datetime类型 df['Date'] = pd.to_datetime(df['Date']) # 计算相邻行的日期间隔,第一行无前置行,填充为0 df['days_diff'] = df['Date'].diff().dt.days.fillna(0)
步骤2:生成分组ID
判断间隔是否超过365天,生成拆分标记,再用cumsum()生成连续的分组ID:
# 当日期间隔>365天时标记为1,否则为0 df['group_flag'] = (df['days_diff'] > 365).astype(int) # 累加标记生成分组ID,同一个连续块会有相同ID df['group_id'] = df['group_flag'].cumsum()
步骤3:按分组聚合
最后按group_id分组,聚合出需要的结果:
result = df.groupby('group_id').agg( Min_Date=('Date', 'min'), Max_Date=('Date', 'max'), Data=('Data', ''.join) ).reset_index(drop=True) # 可选:将日期格式化为字符串(按需调整) result['Min_Date'] = result['Min_Date'].dt.strftime('%Y-%m-%d') result['Max_Date'] = result['Max_Date'].dt.strftime('%Y-%m-%d') print(result)
代码运行结果
Min_Date Max_Date Data 0 2019-01-01 2020-04-01 ABC 1 2021-07-01 2022-02-01 DE 2 2024-05-01 2024-05-01 F
关键逻辑说明
diff().dt.days:必须先将Date转为datetime类型,才能用dt访问器提取天数差。group_flag:标记出需要拆分块的位置,每出现一次间隔>365天,就开启一个新分组。cumsum():将标记累加,把连续的行归为同一个分组ID,确保多块场景下分组准确。
内容的提问来源于stack exchange,提问作者pranavhgupta
相关产品推荐
相关产品推荐

