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

解决匹配DataFrame时间窗口时KeyError: Timestamp不在索引中的问题

问题分析与解决

错误原因

原代码的核心问题在于:你试图用单个时间戳去索引IntervalIndex类型的索引,但IntervalIndex的索引元素是区间对象而非时间戳,当时间戳不落在任何定义的区间内时,就会触发KeyError。

修改方案

我们需要先为df2中的每个时间戳匹配对应的区间(无匹配则标记为无效),再过滤无效数据后分组计算均值,具体有两种实现方式:

方法一:使用apply匹配区间

通过自定义函数检查每个时间戳是否落在某个区间内,无匹配则返回空值,最后过滤空值分组:

from datetime import datetime, date
import pandas as pd

df1 = pd.DataFrame({'id': ['aa0', 'aa1', 'aa2', 'aa3'],
                   'number': [1, 2, 2, 1],
                   'color': ['blue', 'red', 'yellow', "green"],
                   'date1': [datetime(2022,1,1,1,1,1), 
                                  datetime(2022,1,1,2,4,1), 
                                  datetime(2022,1,1,3,8,1), 
                                  datetime(2022,1,1,4,12,1)],
                   'date2': [datetime(2022,1,1,2,1,1), 
                                datetime(2022,1,1,3,6,1), 
                                datetime(2022,1,1,3,10,1), 
                                datetime(2022,1,1,4,14,1)] })

df2 = pd.DataFrame({'id': ['A', 'B', 'C', 'D'],
                   'value': [10,20,30,40],
                   'date': [datetime(2022,1,1,1,12,1), 
                                  datetime(2022,1,1,1,40,1), 
                                  datetime(2022,1,1,3,12,2), 
                                  datetime(2022,1,1,4,12,2)] })

# 生成区间索引(默认左开右闭,符合预期的(date1, date2]格式)
idx = pd.IntervalIndex.from_arrays(pd.to_datetime(df1['date1']), pd.to_datetime(df1['date2']))

# 自定义函数匹配区间
def match_interval(dt):
    # 找到包含当前时间戳的区间
    matched = idx[idx.contains(dt)]
    return matched.item() if len(matched) > 0 else pd.NA

# 为df2添加区间列
df2['interval'] = df2['date'].apply(match_interval)

# 过滤无匹配的行,分组计算均值
result = df2.dropna(subset=['interval']).groupby('interval')['value'].mean()
print(result)

方法二:使用get_indexer_for批量匹配

利用IntervalIndex.get_indexer_for批量获取每个时间戳对应的区间索引,-1表示无匹配,过滤后分组:

from datetime import datetime, date
import pandas as pd

df1 = pd.DataFrame({'id': ['aa0', 'aa1', 'aa2', 'aa3'],
                   'number': [1, 2, 2, 1],
                   'color': ['blue', 'red', 'yellow', "green"],
                   'date1': [datetime(2022,1,1,1,1,1), 
                                  datetime(2022,1,1,2,4,1), 
                                  datetime(2022,1,1,3,8,1), 
                                  datetime(2022,1,1,4,12,1)],
                   'date2': [datetime(2022,1,1,2,1,1), 
                                datetime(2022,1,1,3,6,1), 
                                datetime(2022,1,1,3,10,1), 
                                datetime(2022,1,1,4,14,1)] })

df2 = pd.DataFrame({'id': ['A', 'B', 'C', 'D'],
                   'value': [10,20,30,40],
                   'date': [datetime(2022,1,1,1,12,1), 
                                  datetime(2022,1,1,1,40,1), 
                                  datetime(2022,1,1,3,12,2), 
                                  datetime(2022,1,1,4,12,2)] })

idx = pd.IntervalIndex.from_arrays(pd.to_datetime(df1['date1']), pd.to_datetime(df1['date2']))

# 获取每个时间戳对应的区间索引,-1表示无匹配
interval_indices = idx.get_indexer_for(df2['date'])

# 过滤无匹配的行,并添加区间列
valid_df = df2[interval_indices != -1].copy()
valid_df['interval'] = idx[interval_indices[interval_indices != -1]]

# 分组计算均值
result = valid_df.groupby('interval')['value'].mean()
print(result)

输出结果

两种方法都会得到预期输出:

(2022-01-01 01:01:01, 2022-01-01 02:01:01]    15.0
(2022-01-01 04:12:01, 2022-01-01 04:14:01]    40.0
dtype: float64

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 16:25:29