You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas DataFrame中提取所有区间并计算重叠段N列总和

解决方法

方法一:基础实现(适合小数据量)

1. 提取所有时间临界点

把原始数据里的Start和End值全部收集起来,去重后排序,这些点就是拆分区间的边界:

import pandas as pd

# 构造原始数据
df = pd.DataFrame({
    'Id': [1,2,3,4],
    'Start': [0,0,10,15],
    'End': [10,10,20,25],
    'N': [10,10,5,10]
})

# 提取并排序所有时间点
time_points = sorted(set(df['Start'].tolist() + df['End'].tolist()))

2. 生成拆分后的区间

用相邻的时间点组成新的区间:

intervals = pd.DataFrame({
    'Start': time_points[:-1],
    'End': time_points[1:]
})

3. 计算每个区间的N值总和

对每个拆分后的区间,筛选出所有和它重叠的原始行,把这些行的N加起来:

def get_overlap_sum(row):
    # 判断原始行与当前区间是否重叠:原始Start < 当前End,且原始End > 当前Start
    overlap_mask = (df['Start'] < row['End']) & (df['End'] > row['Start'])
    return df.loc[overlap_mask, 'N'].sum()

intervals['Sum'] = intervals.apply(get_overlap_sum, axis=1)

运行后intervals就是目标结果,和示例输出完全一致。


方法二:向量化实现(适合大数据量)

如果数据量很大,apply循环效率低,用事件累积的思路优化:

1. 生成事件数据

把每个原始区间的Start标记为“+N”事件,End标记为“-N”事件:

# 生成Start事件(加N)
start_events = df[['Start', 'N']].rename(columns={'Start': 'Time', 'N': 'Delta'})
# 生成End事件(减N)
end_events = df[['End', 'N']].rename(columns={'End': 'Time', 'N': 'Delta'})
end_events['Delta'] = -end_events['Delta']

# 合并所有事件
events = pd.concat([start_events, end_events]).sort_values('Time').reset_index(drop=True)

2. 计算累积和

按时间排序后,计算Delta的累积和,这个累积和就是对应时间段的N值总和:

events['CumSum'] = events['Delta'].cumsum()

3. 生成最终区间

用相邻时间点组成区间,对应的累积和就是该区间的总和:

result = pd.DataFrame({
    'Start': events['Time'][:-1],
    'End': events['Time'][1:],
    'Sum': events['CumSum'][:-1]
})

# 去重(处理同一时间点的多个事件)
result = result.drop_duplicates(subset=['Start', 'End']).reset_index(drop=True)

这种方法全程用向量化操作,速度比循环快很多,适合处理十万级以上的数据。


内容的提问来源于stack exchange,提问作者G. Bittencourt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 20:22:51