如何快速筛选落入多时间区间的Pandas DataFrame时间戳?
高效筛选落入指定时间区间的Pandas时间戳数据
问题背景
你需要从包含时间戳序列的DataFrame中,筛选出落入另一DataFrame指定时间区间内的数据,当前使用apply结合自定义函数的方式实现,但处理速度较慢,希望找到更优的性能方案。
原实现及性能瓶颈
你的原代码通过逐行调用自定义函数判断每个时间戳是否在任意区间内,这种逐行处理的方式在Pandas中属于低效操作——apply本质是循环遍历,无法利用Pandas的向量化优化能力,数据量越大,性能问题越明显。
原代码及性能测试:
import pandas as pd # 时间戳DataFrame df = pd.DataFrame(pd.date_range('20180117', end='20180118', freq='60s'), columns=['time']) # 时间区间DataFrame df2= pd.DataFrame([[pd.Timestamp('201801170005'), pd.Timestamp('201801170020')], [pd.Timestamp('201801171415'), pd.Timestamp('201801171430')], [pd.Timestamp('201801171800'), pd.Timestamp('201801171900')]], columns=['start','end']) def flag_during(timestamp, df): """判断时间戳是否落入任意[start, end]区间""" return any((df['start']<timestamp) & (timestamp<df['end'])) # 添加标识列 %timeit df['During'] = df['time'].apply(lambda l: flag_during(l, df2))
测试结果:
682 ms ± 2.71 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
优化方案:利用IntervalIndex的向量化操作
通过Pandas的IntervalIndex可以将时间区间转化为专门的索引对象,再使用get_indexer方法批量匹配时间戳,这种方式完全利用了Pandas的向量化优化,性能提升非常显著。
优化后的代码及性能测试:
%%timeit idx = pd.IntervalIndex.from_arrays(df2['start'], df2['end'], closed='both') event = ~pd.isna(df2['start'].reindex(idx.get_indexer(df['time']))) df['During2'] = event.values
测试结果:
826 µs ± 7.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
性能对比
优化后的方案速度提升了约1000倍,核心原因是:
- 彻底避免了逐行循环,改用向量化的区间匹配操作
IntervalIndex是Pandas专门为区间查询优化的数据结构,内部实现更高效
内容的提问来源于stack exchange,提问作者Steve
相关产品推荐
相关产品推荐

