Pandas如何通过groupby分组计算多个DatetimeIndex的交集
按索引分组计算多日期区间共同交集的Pandas实现
你要的需求完全可以实现,优先推荐用边界计算的高性能方案,避免生成大量日期序列浪费内存。
方案1:高性能边界计算法(推荐)
核心逻辑:多个日期区间的共同重叠区间,必然是所有区间起始时间的最大值到所有区间结束时间的最小值。如果计算得到的起始时间大于结束时间,说明没有重叠,返回空的DatetimeIndex即可。
代码实现:
import pandas as pd # 你的示例数据 df = pd.DataFrame([['2020-01-01', '2020-12-31'], ['2020-01-01', '2020-02-29'], ['2020-01-01', '2020-12-31'], ['2020-06-01', '2020-12-31'], ['2020-08-01', '2020-10-31']], columns=['start', 'end'], index=list('AABBB')) # 先把日期列转为datetime格式 df[['start', 'end']] = df[['start', 'end']].apply(pd.to_datetime) # 按索引分组计算重叠区间的边界 group_result = df.groupby(level=0).agg( overlap_start=('start', 'max'), overlap_end=('end', 'min') ) # 生成最终的重叠DatetimeIndex group_result['overlap_datetime_index'] = group_result.apply( lambda x: pd.date_range(x['overlap_start'], x['overlap_end']) if x['overlap_start'] <= x['overlap_end'] else pd.DatetimeIndex([]), axis=1 )
运行后结果:
- 索引A的overlap_datetime_index为
2020-01-01到2020-02-29的DatetimeIndex,符合预期 - 索引B的overlap_datetime_index为
2020-08-01到2020-10-31的DatetimeIndex,符合预期
方案2:基于DatetimeIndex.intersection迭代计算
如果你需要严格用intersection方法实现(比如后续有更复杂的交集逻辑),可以用reduce迭代计算多个DatetimeIndex的交集:
from functools import reduce import pandas as pd # 沿用你之前生成period_range的逻辑 df = pd.DataFrame([['2020-01-01', '2020-12-31'], ['2020-01-01', '2020-02-29'], ['2020-01-01', '2020-12-31'], ['2020-06-01', '2020-12-31'], ['2020-08-01', '2020-10-31']], columns=['start', 'end'], index=list('AABBB')) df['period_range'] = df.apply(lambda x: pd.date_range(x['start'], x['end']), axis=1) # 分组迭代求交集 def get_multi_intersection(idx_list): return reduce(lambda a, b: a.intersection(b), idx_list) result = df.groupby(level=0)['period_range'].apply(get_multi_intersection)
注意事项:该方案需要为每行生成完整的日期序列,日期范围较大时内存占用高、运行速度慢,仅适合小数据量场景使用。
内容的提问来源于stack exchange,提问作者mrk.jhsn
相关产品推荐
相关产品推荐

