如何向量化检查DataFrame索引是否在指定时间区间内
高效检查DataFrame索引是否在任意时间区间内
问题背景
我有一个由pd.Timestamp类型元素组成的时间区间列表:
import pandas as pd import numpy as np intervals = [ [pd.Timestamp('2023-01-01 02:00:00'), pd.Timestamp('2023-01-01 03:00:00')], [pd.Timestamp('2023-01-01 05:00:00'), pd.Timestamp('2023-01-01 07:00:00')], [pd.Timestamp('2023-01-01 07:30:00'), pd.Timestamp('2023-01-01 08:00:00')], ]
同时有一个带时间索引的DataFrame:
data = {'value': [1, 2, 3, 4]} index = [ pd.Timestamp('2023-01-01 01:00:00'), pd.Timestamp('2023-01-01 02:00:00'), pd.Timestamp('2023-01-01 03:00:00'), pd.Timestamp('2023-01-01 04:00:00'), ] df = pd.DataFrame(data, index=index)
需要检查DataFrame的每个索引是否处于任意一个时间区间内,我的思路是:
- 为每个时间区间生成布尔掩码,标记索引是否在该区间内,示例掩码如下:
masks = [ [False, True, True, False], [False, False, False, False], [False, False, False, False], ]
- 将这些掩码通过逻辑或操作合并为单个掩码:
mask = [False, True, True, False]
希望用向量化方式实现,优先用numpy或pandas,当前数据用Python列表管理,请问哪种实现方式最快且最优雅?
最优实现方案
方法1:Numpy广播(性能最优)
利用Numpy的广播特性,一次性完成所有区间的判断,避免循环开销:
# 将时间区间转为形状为(n_intervals, 2)的numpy数组 interval_arr = np.array(intervals) # 将DataFrame索引转为形状为(n_index, 1)的二维数组,用于广播匹配 index_arr = df.index.to_numpy().reshape(-1, 1) # 广播判断:每个索引 >= 区间起始 且 <= 区间结束,结果为(n_index, n_intervals)的布尔矩阵 mask_matrix = (index_arr >= interval_arr[:, 0]) & (index_arr <= interval_arr[:, 1]) # 按行取逻辑或,得到每个索引是否命中任意区间的最终掩码 final_mask = mask_matrix.any(axis=1)
运行结果:array([False, True, True, False]),完全符合需求。
方法2:Pandas IntervalIndex(代码最简洁)
通过pd.IntervalIndex语义化处理时间区间,代码可读性更强:
# 创建包含所有时间区间的IntervalIndex,closed='both'表示区间左右都闭合 interval_idx = pd.IntervalIndex.from_tuples(intervals, closed='both') # 直接用isin方法判断索引是否在任意区间内 final_mask = df.index.isin(interval_idx)
结果与方法1一致,代码更简洁,适合注重可读性的场景。
性能说明
- 当区间数量和索引规模较大时,方法1的Numpy广播速度最快,底层基于C实现,无Python循环开销;
- 方法2的
isin内部也是向量化实现,性能接近方法1,但代码更直观; - 绝对避免用Python循环逐个生成掩码再合并,这种方式在数据量大时性能会差几个数量级。
内容的提问来源于stack exchange,提问作者LucaM
相关产品推荐
相关产品推荐

