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

运行Python代码出现KeyError: ('datetime64[ns]', 'left')错误求解决方案

解决KeyError: ('datetime64[ns]', 'left')问题

嘿,我来帮你搞定这个报错!你遇到的这个KeyError主要是两个原因:一是你用的pandas版本比较旧(看路径是py35的conda环境,pandas版本大概率低于1.0),对datetime64[ns]类型的左闭合IntervalIndex支持不完善;二是原代码里有个潜在问题——当某些时间间隔没有对应数据时,手动分组后的df_res行数和你生成的interval长度不匹配,直接设置索引就会触发错误。

下面给你两个解决方案,优先推荐第一个,简单高效还靠谱:

方案1:用pandas内置的resample直接搞定(最推荐)

你的需求本质就是按固定时间间隔对数据做均值聚合,pandas的resample是专门为这个场景设计的,比自己写循环效率高N倍,还能完美避开手动处理索引的坑:

import pandas as pd
import time

def transform_in_intervals(df, freq='5T'):
    df_copy = df.copy()
    # 确保time列是索引且为datetime类型
    df_copy = df_copy.set_index('time', drop=True)
    # 按5分钟间隔重采样,左闭合,对数值列取均值
    # 空的时间段会自动填充NaN,如果你想填充0可以加.fillna(0)
    resampled_df = df_copy.resample(freq, closed='left').mean(numeric_only=True)
    return resampled_df

start = time.time()
trans_df = transform_in_intervals(merged_df)
end = time.time()
print("time:{:.3f} s".format(end-start))

这个代码不仅简洁,运行速度也会比你原来的循环快很多,完全不需要手动处理区间匹配的逻辑。

方案2:修复原代码的索引问题

如果你一定要用自己写的逻辑,那得解决两个问题:一是保证df_res的行数和interval完全一致,二是兼容旧版本pandas的IntervalIndex问题:

import pandas as pd
import time

def transform_in_intervals(df,freq=pd.to_offset('5t')):
    df_copy = df.copy()
    time_index = df_copy.index
    # 生成完整的时间间隔序列
    interval_count = int((time_index[-1] - time_index[0])/pd.Timedelta(freq)) + 1
    interval = pd.interval_range(start=time_index[0], periods=interval_count, freq=freq, closed="left")
    
    df_copy.reset_index(drop=False, inplace=True)
    df_copy['interval'] = pd.NA  # 先初始化interval列
    
    i, c = 0, 0
    # 给每条数据匹配对应的时间间隔,加边界判断防止越界
    while i < len(df_copy) and c < len(interval):
        if df_copy.loc[i,"time"] in interval[c]:
            df_copy.loc[i,"interval"] = interval[c]
            i += 1
        else:
            c += 1
    
    # 先创建以interval为索引的空DataFrame,确保所有时间段都被包含
    df_res = pd.DataFrame(index=interval)
    # 分组聚合后合并到结果中
    grouped_data = df_copy.groupby("interval").mean(numeric_only=True).drop("time", axis=1)
    df_res = df_res.join(grouped_data)
    
    return df_res

start = time.time()
trans_df = transform_in_intervals(merged_df)
end = time.time()
print("time:{:.3f} s".format(end-start))

这里的关键修改点:

  • 初始化interval列,避免出现未赋值的情况
  • 循环里加了c < len(interval)的判断,防止索引越界
  • 先创建完整的Interval索引的DataFrame,再合并分组结果,确保每个时间段都有对应的行
  • 用numeric_only=True避免对非数值列求均值,防止报错

额外提醒

你用的Python3.5和对应的旧版pandas对datetime类型的Interval支持有不少bug,如果环境允许的话,建议升级到pandas1.0以上的版本,能避免很多这类奇怪的索引问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:13:29