Python中对重叠时间区间关联值求和的实现方案
时间区间重叠求和处理方案
问题背景
现有一个包含时间区间(start_dt、end_dt)及对应关联值(value)的pandas DataFrame,生成该DataFrame的代码如下:
import random import time import numpy as np import pandas as pd import datetime as dt def random_date(input_dt = None): if input_dt is None: start = 921032233 else: start = dt.datetime.timestamp(pd.to_datetime(input_dt)) d = random.randint(start, int(time.time())) return dt.datetime.fromtimestamp(d).strftime('%Y-%m-%d %H:%M:%S') date_ranges = [] for _ in range(200): date_range = [] for i in range(2): if i == 0: date_range.append(random_date()) else: date_range.append(random_date(date_range[0])) date_ranges.append(date_range) date_ranges_df = pd.DataFrame(date_ranges, columns=['start_dt', 'end_dt']) date_ranges_df['value'] = np.random.random((date_ranges_df.shape[0], 1)) # 转换时间列为datetime类型,方便后续处理 date_ranges_df['start_dt'] = pd.to_datetime(date_ranges_df['start_dt']) date_ranges_df['end_dt'] = pd.to_datetime(date_ranges_df['end_dt'])
需求可通过两种方式实现,最终结果DataFrame需包含起止时间及对应求和值列:
- 计算所有不同重叠区间的求和值,得到连续无重叠的时间区间,当重叠的区间集合变化时,重新计算求和值;
- 定义标准时间间隔(如1小时),计算该时段内所有重叠区间的value总和。
方案一:生成无重叠连续区间并计算重叠求和值
实现逻辑
- 提取所有原始区间的起止时间点,去重排序后得到关键时间节点;
- 遍历相邻时间节点组成的子区间,统计每个子区间被多少原始区间覆盖,计算对应的
value总和; - 可选:合并连续且求和值相同的区间,得到最精简的无重叠结果。
代码实现
# 提取所有时间点并去重排序 all_timestamps = pd.concat([date_ranges_df['start_dt'], date_ranges_df['end_dt']]).unique() all_timestamps = np.sort(all_timestamps) # 生成相邻时间点组成的子区间并计算求和值 result_list = [] for i in range(len(all_timestamps)-1): current_start = all_timestamps[i] current_end = all_timestamps[i+1] # 筛选覆盖当前子区间的原始区间 mask = (date_ranges_df['start_dt'] <= current_start) & (date_ranges_df['end_dt'] >= current_end) total_value = date_ranges_df.loc[mask, 'value'].sum()[0] result_list.append({'start_dt': current_start, 'end_dt': current_end, 'sum_value': total_value}) # 转换为结果DataFrame result_df = pd.DataFrame(result_list) # 可选:合并连续且求和值相同的区间 merged = [] for idx, row in result_df.iterrows(): if not merged: merged.append({'start_dt': row['start_dt'], 'end_dt': row['end_dt'], 'sum_value': row['sum_value']}) else: last = merged[-1] if last['sum_value'] == row['sum_value'] and last['end_dt'] == row['start_dt']: last['end_dt'] = row['end_dt'] else: merged.append({'start_dt': row['start_dt'], 'end_dt': row['end_dt'], 'sum_value': row['sum_value']}) merged_result_df = pd.DataFrame(merged)
方案二:按标准时间间隔(小时)计算重叠求和值
实现逻辑
- 确定数据集的整体时间范围,生成按指定间隔(如1小时)划分的时间序列;
- 对每个时间窗口,统计所有与该窗口有重叠的原始区间的
value总和; - 整理成包含起止时间和求和值的结果DataFrame。
代码实现
# 确定整个数据集的时间范围 min_time = date_ranges_df['start_dt'].min() max_time = date_ranges_df['end_dt'].max() # 生成1小时间隔的时间序列,向上/向下取整保证覆盖全部区间 hourly_ranges = pd.date_range(start=min_time.floor('H'), end=max_time.ceil('H'), freq='H') # 遍历每个小时窗口计算求和值 hourly_result = [] for i in range(len(hourly_ranges)-1): window_start = hourly_ranges[i] window_end = hourly_ranges[i+1] # 筛选与当前窗口重叠的区间:原始区间开始早于窗口结束,且原始区间结束晚于窗口开始 mask = (date_ranges_df['start_dt'] < window_end) & (date_ranges_df['end_dt'] > window_start) total_value = date_ranges_df.loc[mask, 'value'].sum()[0] hourly_result.append({'start_dt': window_start, 'end_dt': window_end, 'sum_value': total_value}) hourly_result_df = pd.DataFrame(hourly_result)
内容的提问来源于stack exchange,提问作者conv3d
相关产品推荐
相关产品推荐

