如何高效检测表格中事件是否在D+2日期重复出现
问题
我有一组包含日期及对应事件的数据集(每行对应一个事件),需要判断每个事件在当前行日期的两天后是否再次发生,并为符合条件的行添加TRUE标记,否则为FALSE。由于实际数据集达数百兆,逐行循环遍历全表的方案效率极低,需要更优解法。
原始数据示例:
date event 01/01/2000 a 01/01/2000 b 01/01/2000 c 01/01/2000 d 02/01/2000 e 02/01/2000 f 02/01/2000 g 02/01/2000 h 03/01/2000 i 03/01/2000 j 03/01/2000 k 03/01/2000 a 04/01/2000 l 04/01/2000 m 04/01/2000 b 04/01/2000 o
期望输出结果:
date event repeat_D2 01/01/2000 a TRUE 01/01/2000 b FALSE 01/01/2000 c FALSE 01/01/2000 d FALSE 02/01/2000 e FALSE 02/01/2000 f FALSE 02/01/2000 g FALSE 02/01/2000 h FALSE 03/01/2000 i FALSE 03/01/2000 j FALSE 03/01/2000 k FALSE 03/01/2000 a FALSE 04/01/2000 l FALSE 04/01/2000 m FALSE 04/01/2000 b FALSE 04/01/2000 o FALSE
高效解决方案
针对大数据量,推荐使用向量化操作替代循环,利用Pandas的分组、合并等内置功能实现O(n)级别的处理效率,以下提供两种最优方案:
方案1:基于集合快速查询
先预存每个事件的所有出现日期,再通过集合的O(1)查询判断目标日期是否存在:
import pandas as pd # 读取数据(根据实际数据源调整分隔符/读取方式) df = pd.read_csv('your_data.csv', sep='\t') # 将日期列转换为datetime类型,支持日期运算 df['date'] = pd.to_datetime(df['date'], format='%d/%m/%Y') # 按事件分组,收集每个事件的所有日期并转为集合 event_date_sets = df.groupby('event')['date'].apply(set).to_dict() # 快速判断当前日期+2天是否在该事件的日期集合中 df['repeat_D2'] = df.apply( lambda row: (row['date'] + pd.Timedelta(days=2)) in event_date_sets[row['event']], axis=1 ) # 输出结果(保持制表符分隔格式) print(df.to_csv(sep='\t', index=False))
方案2:全向量化合并(性能最优)
通过创建临时表并合并,完全避免逐行操作,适合超大规模数据集:
import pandas as pd df = pd.read_csv('your_data.csv', sep='\t') df['date'] = pd.to_datetime(df['date'], format='%d/%m/%Y') # 创建临时表:存储每个事件的「日期-2天」与原日期的映射 temp_df = df[['event', 'date']].copy() temp_df['target_date'] = temp_df['date'] temp_df['date'] -= pd.Timedelta(days=2) # 合并原表与临时表,判断是否存在匹配项 df = df.merge( temp_df[['event', 'date', 'target_date']], on=['event', 'date'], how='left', indicator='repeat_D2' ) # 将合并结果转换为TRUE/FALSE标记 df['repeat_D2'] = df['repeat_D2'] == 'both' # 输出结果 print(df.to_csv(sep='\t', index=False))
方案优势
- 两种方案均避免了遍历全表的低效操作,时间复杂度远低于循环法
- 方案2完全依赖Pandas的向量化引擎,性能比方案1更优,适合数百兆级别的数据集
- 集合查询和合并操作都是Pandas内部优化的C级实现,比Python循环快100~1000倍
内容的提问来源于stack exchange,提问作者Aytan
相关产品推荐
相关产品推荐

