Pandas实现合并重叠/相邻时间区间并删除被包含区间
需求说明
我需要基于pandas实现以下两个时间区间处理功能:
- 合并相邻(间隔恰好为1天)或存在部分重叠的时间区间
- 移除区间完全被其他区间包含的行
测试数据集
使用的示例数据集代码如下:
import pandas as pd df = pd.DataFrame([ [42,1,'1990-01-01','2099-12-31'], [42,2,'1990-01-01','2099-12-31'], [42,2,'2010-10-01','2016-02-29'], [42,2,'2011-09-01','2014-09-30'], [42,2,'2012-04-01','2016-07-31'], [42,2,'2013-04-01','2014-06-30'], [42,2,'2013-09-01','2014-02-28'], [42,2,'2014-03-01','2017-04-30'], [42,2,'2014-10-01','2017-10-31'], [42,2,'2015-04-01','2015-12-31'], [42,2,'2016-03-01','2020-03-31'], [42,2,'2016-08-01','2016-12-31'], [42,2,'2017-01-01','2018-08-31'], [42,2,'2017-05-01','2018-12-31'], [42,2,'2017-11-01','2021-06-14'], [42,2,'2018-09-01','2019-01-31'], [42,2,'2019-02-01','2019-05-31'], [42,2,'2019-04-01','2021-03-31'], [42,2,'2019-06-01','2020-07-31'], [42,2,'2020-08-01','2021-03-14'], [42,2,'2021-03-15','2021-06-30'], [43,1,'1998-01-01','2001-12-31'], [43,1,'2010-03-15','2021-06-30'], [43,1,'2021-01-01','2021-12-31'], [43,2,'1998-01-01','1998-12-31'], [43,2,'1999-01-01','2000-12-31'], [43,2,'2001-01-01','2021-06-30'] ], columns=['Id', 'SubId', 'Start', 'End']) df['Start'] = pd.to_datetime(df['Start']) df['End'] = pd.to_datetime(df['End'])
预期输出
处理后期望得到如下结果:
42, 1, 1990-01-01, 2099-12-31 42, 2, 1990-01-01, 2099-12-31 43, 1, 1998-01-01, 2001-12-31 43, 1, 2010-03-15, 2021-12-31 43, 2, 1998-01-01, 2021-06-30
已测试的无效方案
参考同类连续日期合并问题的方案编写了如下代码,但无法得到预期结果:
df = df.sort_values(['Id', 'SubId', 'Start']) day_diff = (df['Start'] - df['End'].groupby([df['Id'], df['SubId']]).shift()).dt.days group_no = (day_diff.isna() | day_diff.gt(1)).cumsum() df_out = (df.groupby(['Id', 'SubId', group_no], dropna=False, as_index=False) .agg({'Id': 'first', 'SubId': 'first', 'Start': 'first', 'End': lambda x: x.iloc[-1] }))
该方案仅在所有区间均为相邻关系时可正常运行,如果存在覆盖范围更大的跨子区间总区间,方案无法记录总区间的完整范围,会输出错误结果,错误输出示例如下:
42 ,1 , 1990-01-01, 2099-12-31 42 ,2 , 1990-01-01, 2015-12-31 <-- 结束日期错误,预期应为2099-12-31 42 ,2 , 2016-03-01, 2021-06-30 <-- 错误,该条不应存在,应合并入上一条区间 43 ,1 , 1998-01-01, 2001-12-31 43 ,1 , 2010-03-15, 2021-12-31 43 ,2 , 1998-01-01, 2021-06-30
问题
按相同Id、SubId配对分组遍历处理时,是否可以通过跟踪分组内的最小Start、最大End值来实现正确的区间合并逻辑?
内容的提问来源于stack exchange,提问作者Benjamin
相关产品推荐
相关产品推荐

