Python Pandas 快速实现大量重叠日期区间观测值按日求和聚合
重叠日期区间每日聚合值高效计算方案
核心思路
采用差分扫描线算法,避免展开所有日期区间的高开销操作:
- 对每条观测记录,生成两个事件:区间起始日加对应
value,区间结束日的后一天减对应value - 按日期聚合所有事件的增量值后,计算前缀和即可得到每日的累计总和
实现代码
import pandas as pd # 原始数据构造代码可直接复用 data = pd.DataFrame({ 'start_date':pd.to_datetime(['2021-01-07','2021-01-04','2021-01-12','2021-01-03']), 'end_date':pd.to_datetime(['2021-01-16','2021-01-12','2021-01-13','2021-01-15']), 'value':[7,6,5,4] }) # 构造差分事件 events = pd.concat([ # 起始日加对应value pd.DataFrame({'date': data['start_date'], 'delta': data['value']}), # 结束日次日减对应value(结束日当天仍需计入统计) pd.DataFrame({'date': data['end_date'] + pd.Timedelta(days=1), 'delta': -data['value']}) ]) # 按日期聚合单日所有增量 daily_delta = events.groupby('date', as_index=True)['delta'].sum() # 生成完整日期序列,补全无事件日期的增量为0,计算前缀和得到最终结果 full_date_range = pd.date_range( start = daily_delta.index.min(), end = daily_delta.index.max() - pd.Timedelta(days=1), freq = 'D' ) result = daily_delta.reindex(full_date_range, fill_value=0).cumsum()
性能说明
- 原循环方案时间复杂度为
O(N*L),N为观测数、L为平均区间长度,当观测量级达10万、平均区间为10天时,会生成百万级中间数据,concat阶段内存开销极高易崩溃 - 本方案时间复杂度为
O(N + M),N为观测数、M为总统计天数,仅需要处理2倍观测数的事件点,所有操作均为pandas原生向量化实现,10万条观测可在秒级完成计算,内存占用降低90%以上
内容的提问来源于stack exchange,提问作者curious_know_nothing
相关产品推荐
相关产品推荐

