You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何向量化检查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的每个索引是否处于任意一个时间区间内,我的思路是:

  1. 为每个时间区间生成布尔掩码,标记索引是否在该区间内,示例掩码如下:
masks = [
   [False, True, True, False],
   [False, False, False, False],
   [False, False, False, False],
]
  1. 将这些掩码通过逻辑或操作合并为单个掩码:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 16:20:05