Pandas循环计算MAPE抛出KeyError:0错误如何解决
错误原因
你的代码存在两个直接触发报错、且逻辑不符合预期的问题:
- 初始化的
mape_hm是无任何行列的空DataFrame,执行mape_hm[i][e]赋值时,Pandas会优先查找列名为i(第一次循环i=0)的列,空表不存在该列,直接抛出KeyError:0。 - 就算绕开空表赋值问题,原有逻辑既没有处理MAPE结果和原表的行对齐,也没有按照要求生成带
MAPE_前缀的列名,最终输出结构和预期不符。 - 你要求保留
lista_com的嵌套列表结构,原有循环的索引遍历逻辑本身没问题,问题出在赋值和结果拼接的环节。
修正代码
完全保留你给定的嵌套列表lista_com结构、双层循环框架,只修正赋值和结果拼接逻辑,代码如下:
import pandas as pd from sklearn.metrics import mean_absolute_percentage_error # 原始数据与初始化参数保持原样 df1 = pd.DataFrame({'id' : [1, 2, 1,2], 'plat' : ['and','and','ios','ios'], 'd30_real' : [1.2,1.4,1.5,1.9], 'd3_d30':[1.1,1.5,1.5,1.8], 'd7_d30':[1.4,1.5,1.6,1.9], 'd14_d30':[1.2,1.3,1.5,2.0]}) lista_target = ['d30_real'] lista_com = [['d3_d30','d7_d30','d14_d30']] # 以原始df为基表,保留所有原始字段,避免空表赋值问题 result = df1.copy() for i in range(len(lista_target)): target_col = lista_target[i] for e in range(len(lista_com[i])): pred_col = lista_com[i][e] # 按指定维度分组计算MAPE,重命名为要求的列名 mape_res = df1.groupby(['id','plat']).apply( lambda x: mean_absolute_percentage_error(x[target_col], x[pred_col]) ).rename(f'MAPE_{pred_col}').reset_index() # 按分组键将MAPE结果合并回基表,自动对齐行 result = result.merge(mape_res, on=['id','plat'], how='left')
运行后得到的result结构和你要求的完全一致,实际计算值如下(你给出的示例为虚拟值,以下为真实计算结果):
id plat d30_real d3_d30 d7_d30 d14_d30 MAPE_d3_d30 MAPE_d7_d30 MAPE_d14_d30 0 1 and 1.2 1.1 1.4 1.2 0.083333 0.166667 0.000000 1 2 and 1.4 1.5 1.5 1.3 0.071429 0.071429 0.071429 2 1 ios 1.5 1.5 1.6 1.5 0.000000 0.066667 0.000000 3 2 ios 1.9 1.8 1.9 2.0 0.052632 0.000000 0.052632
说明:当前每个(id, plat)分组仅包含1条样本,因此分组计算的MAPE等价于单条样本的相对误差,符合当前数据场景。
内容的提问来源于stack exchange,提问作者MatmataHi
相关产品推荐
相关产品推荐

