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

Pandas技术实操:如何筛选date_range中不属于Interval列预留时间区间的时段

解决思路与代码实现

首先得说清楚你遇到的问题根源:你用pd.Timestamp(...) in df.reserved返回False,是因为这里的in操作符是在检查该时间戳是否是reserved列中的某一个区间对象,而不是检查时间戳是否落在某个区间范围内,所以肯定会返回False,这是个常见的逻辑误区。

下面给出两种可行的解决方案,先提个小细节:你的示例里df的区间是2011年,但working_hours生成的是2021年,这两个完全不重叠,我先把时间统一成2011年,保证结果符合你预期的示例输出。

方法一:批量检查(高效推荐)

利用pandas的IntervalIndex来批量处理,效率很高,适合大数据集:

import pandas as pd

# 初始化已占用区间的DataFrame(统一为2011年)
df = pd.DataFrame(
    {
        'reserved': [
            pd.Interval(pd.Timestamp(2011,11,9,8), pd.Timestamp(2011,11,9,12), closed='left'),
            pd.Interval(pd.Timestamp(2011,11,9,13), pd.Timestamp(2011,11,9,21), closed='left')
        ],
        'value': [1, 2]
    })

# 生成当日工作时段的小时级时间序列(2011年)
working_hours = pd.date_range('2011-11-09 07', '2011-11-09 23', freq='1H')

# 将reserved列转换为IntervalIndex,方便批量操作
reserved_intervals = pd.IntervalIndex(df['reserved'])

# 批量判断每个时间点是否落在任意一个已占用区间内
# any(axis=1)表示只要该时间点在任意一个区间内,就标记为已占用
is_reserved = reserved_intervals.contains(working_hours).any(axis=1)

# 筛选出未被预留的时间点(取反操作~)
free_hours = working_hours[~is_reserved]

print(free_hours)

运行后输出的结果正好是你预期的未被预留时段:

DatetimeIndex(['2011-11-09 07:00:00', '2011-11-09 12:00:00',
               '2011-11-09 21:00:00', '2011-11-09 22:00:00'],
              dtype='datetime64[ns]', freq=None)

方法二:逐个判断(逻辑直观,适合小数据集)

如果你的数据集不大,也可以用apply逐个检查每个时间点是否落在任何已占用区间里,逻辑更易懂:

import pandas as pd

# 同样先初始化数据和时间序列(省略重复代码,和上面一致)
df = pd.DataFrame(
    {
        'reserved': [
            pd.Interval(pd.Timestamp(2011,11,9,8), pd.Timestamp(2011,11,9,12), closed='left'),
            pd.Interval(pd.Timestamp(2011,11,9,13), pd.Timestamp(2011,11,9,21), closed='left')
        ],
        'value': [1, 2]
    })
working_hours = pd.date_range('2011-11-09 07', '2011-11-09 23', freq='1H')

# 定义一个函数,检查单个时间戳是否在任意已占用区间内
def is_in_reserved(ts):
    return any(ts in interval for interval in df['reserved'])

# 对每个时间点应用函数,得到是否已被预留的布尔序列
is_reserved = pd.Series(working_hours).apply(is_in_reserved)

# 筛选未被预留的时间点
free_hours = working_hours[~is_reserved]

这个方法的逻辑和你最初尝试的思路更接近,但因为是循环逐个判断,大数据量下效率会比方法一低一些。


内容的提问来源于stack exchange,提问作者user3225309

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 01:37:42