pandas高效查找日期区间重叠行及获取重叠行索引的方法
高效实现方案
你原有的双层循环是O(n²)时间复杂度,针对数十万行的数据集性能会极差,以下提供两种经过验证的高效实现方案:
方案一:pandas IntervalIndex 实现(代码简洁易维护)
利用pandas内置的区间索引能力直接查询重叠区间,底层做过性能优化,比手动写循环效率高几十倍,适合绝大多数场景:
import pandas as pd # 第一步:确保时间字段为datetime类型 df['start_dtm'] = pd.to_datetime(df['start_dtm']) df['end_dtm'] = pd.to_datetime(df['end_dtm']) # 构造区间索引,closed='both'表示区间包含首尾,完全匹配你原有的重叠判断逻辑 # 如果你的区间是左闭右开,可修改为closed='left' ivs = pd.IntervalIndex.from_arrays(df['start_dtm'], df['end_dtm'], closed='both') # 定义获取单条记录重叠索引的方法 def get_overlap_indexes(current_idx): current_interval = ivs[current_idx] # 查询所有重叠的区间索引,排除自身 overlap_list = ivs[ivs.overlaps(current_interval)].index.tolist() overlap_list.remove(current_idx) return overlap_list # 初始化结果列 df['has_overlap'] = False df['overlap_indexes'] = [[] for _ in range(len(df))] # 遍历填充结果 for idx in df.index: overlaps = get_overlap_indexes(idx) if overlaps: df.loc[idx, 'has_overlap'] = True df.loc[idx, 'overlap_indexes'] = overlaps
方案二:排序扫描法(性能最优,适合超大数据集)
仅需一次排序+一次线性扫描即可完成重叠判断,时间复杂度为O(nlogn),百万行级别数据也可以秒出结果:
# 先保留原始索引,按起始时间排序 df_sorted = df[['start_dtm', 'end_dtm']].reset_index().sort_values('start_dtm', ignore_index=True) overlap_groups = [] current_group = [0] current_max_end = df_sorted.loc[0, 'end_dtm'] # 一次扫描划分重叠组 for i in range(1, len(df_sorted)): if df_sorted.loc[i, 'start_dtm'] <= current_max_end: current_group.append(i) current_max_end = max(current_max_end, df_sorted.loc[i, 'end_dtm']) else: overlap_groups.append(current_group) current_group = [i] current_max_end = df_sorted.loc[i, 'end_dtm'] overlap_groups.append(current_group) # 将结果映射回原始表 for group in overlap_groups: if len(group) >= 2: # 组内元素数>=2才存在重叠 original_indexes = df_sorted.loc[group, 'index'].tolist() for idx in original_indexes: df.loc[idx, 'has_overlap'] = True df.loc[idx, 'overlap_indexes'] = [x for x in original_indexes if x != idx]
内容的提问来源于stack exchange,提问作者00__00__00
相关产品推荐
相关产品推荐

