如何在Pandas DataFrame中查询特定分组的重叠有效期记录
问题分析
你写的代码存在几个核心错误导致无法正确识别重叠记录:
- 缺少
datetime模块导入,代码中使用的timedelta会直接抛出未定义报错 - 未对分组内的记录按有效起始日期排序,直接使用
shift()取上一行记录,行顺序完全依赖文件原始存储顺序,判断逻辑不成立 - 重叠区间的判断逻辑完全错误:两个时间段[start1, end1]、[start2, end2](假设start2 >= start1)的重叠条件是
start2 <= end1,原代码写的是前一个的start - 当前的end >0,这是判断两个时间段完全不重叠的条件,和需求完全相反 - 仅对比相邻行的逻辑,在未排序的场景下无法覆盖所有重叠可能,比如存在3条记录交叉重叠的场景会漏判
修正后代码
import pandas as pd from datetime import timedelta # 补全缺失的导入 df_fares = pd.read_csv('input.csv', sep='|') # 日期类型转换逻辑保持不变 df_fares.eff_start_date = pd.to_datetime(df_fares.eff_start_date, format='%Y-%m-%d') df_fares.eff_end_date = pd.to_datetime(df_fares.eff_end_date, format='%Y-%m-%d') def check_overlap(group): # 先把分组内的记录按生效开始日期、生效结束日期排序 group = group.sort_values(['eff_start_date', 'eff_end_date']).reset_index(drop=True) # 记录每个分组内所有涉及重叠的行索引 overlap_indices = set() # 双重循环遍历所有记录对,确保没有漏判 for i in range(len(group)): for j in range(i+1, len(group)): # 核心重叠判断逻辑 if group.loc[i, 'eff_start_date'] <= group.loc[j, 'eff_end_date'] and group.loc[j, 'eff_start_date'] <= group.loc[i, 'eff_end_date']: overlap_indices.add(i) overlap_indices.add(j) # 新增overlap列,True表示当前记录存在重叠 group['overlap'] = group.index.isin(overlap_indices) return group # 分组应用校验逻辑 df_fares = df_fares.groupby(['origin', 'destination', 'class'], group_keys=False).apply(check_overlap)
结果验证
运行后你可以通过df_fares[df_fares['overlap'] == True]筛选所有存在冲突的记录,你给出的示例中索引为7、8的两条记录会被正确标记为重叠。
如果仅需要判断整个文件是否存在冲突,不需要逐行标记,直接执行print(df_fares['overlap'].any())即可,返回True表示存在冲突。
内容的提问来源于stack exchange,提问作者Mohan
相关产品推荐
相关产品推荐

