优化Pandas日期条件分组逻辑:兼容有无间隔场景
Pandas日期分组的Gap-Island逻辑优化
问题背景
此前实现Pandas基于日期条件的行分组功能,封装通用函数时遇到场景适配问题:
- 无偏移执行24H重采样,可得到正确的按天分组结果;
- 执行偏移场景所需的Gap-Island代码时,会错误将周五(2023-03-17)和周一(2023-03-20)的数据合并为一行。
需求是改进Gap-Island逻辑,无需if分支判断,同时适配两种场景:
- 无间隔(如连续工作日的每日块):保留原分组,不合并;
- 24H数据块跨间隔(如周末无数据导致的块间隙):合并相邻数据。
测试数据
import pandas as pd data = { "date_time": [ "2023-03-15 00:00:00", "2023-03-15 06:00:00", "2023-03-15 12:00:00", "2023-03-15 18:00:00", "2023-03-16 00:00:00", "2023-03-16 06:00:00", "2023-03-16 12:00:00", "2023-03-16 18:00:00", "2023-03-17 00:00:00", "2023-03-17 06:00:00", "2023-03-17 12:00:00", "2023-03-17 18:00:00", "2023-03-20 06:00:00" ], "day": [3,3,3,3,4,4,4,4,5,5,5,5,1], "value1": [1,2,3,4,5,6,7,8,9,10,11,12,13], "value2": [1,2,3,4,5,6,7,8,9,10,11,12,13] } df = pd.DataFrame(data) df["date_time"] = pd.to_datetime(df["date_time"])
无偏移重采样代码
agg_dict = { "date_time": "last", "day": "last", "value1": "first", "value2": "last", } rows = df.resample("24H", on="date_time").agg(agg_dict).dropna()
原Gap-Island代码(存在问题)
island = rows.index.to_series().diff().le("1D").cumsum().rename("island") rows = rows.groupby(island).agg(agg_dict)
改进后的Gap-Island逻辑
方案1:解决周五与周一错误合并问题
核心是调整岛的划分规则:仅间隔≤1天的连续块合并,间隔>1天的块独立成组。
# 计算相邻块的时间差,判断是否需要新起分组 island = (rows.index.to_series().diff() > pd.Timedelta(days=1)).cumsum().rename("island") rows = rows.groupby(island).agg(agg_dict)
逻辑说明:
- 相邻块间隔≤1天:视为连续业务块,合并为同一组;
- 相邻块间隔>1天:视为独立业务块,单独分组。
方案2:同时支持跨周末间隙合并
如果需要合并周末无数据导致的周五-周一间隙块,可添加额外判断:
diff = rows.index.to_series().diff() # 判断是否为周五到周一的周末间隙(间隔3天,前块是周五,后块是周一) is_weekend_gap = (diff == pd.Timedelta(days=3)) & (rows.index.shift(1).dt.dayofweek == 4) & (rows.index.dt.dayofweek == 0) # 仅当间隔>1天且非周末间隙时,新起分组 new_island = (diff > pd.Timedelta(days=1)) & (~is_weekend_gap) island = new_island.cumsum().rename("island") rows = rows.groupby(island).agg(agg_dict)
逻辑说明:
- 连续工作日的每日块:间隔≤1天,独立分组;
- 周五到周一的间隙块:合并为同一组;
- 其他间隔>1天的块:独立分组。
内容的提问来源于stack exchange,提问作者Wannabe-Coder
相关产品推荐
相关产品推荐

