Pandas对DataFrame两列应用自定义MAPE函数时触发ValueError错误求助
问题解决方案
错误触发原因
- 第一处错误是
apply调用时传参错误:你在lambda里传入的df.Actuals_March和df.Forecast_March是完整的列数据(Series类型),不是当前行的单个数值。执行if actual == 0判断时相当于拿整个Series和0比较,返回的是布尔类型的Series,Python无法直接判断布尔Series的真值,因此触发对应的ValueError。 - 第二处错误是自定义MAPE函数的逻辑和逐行计算的需求不匹配:你当前的需求是给每行生成一个MAPE值存入新列,函数内不需要调用
np.mean,只有计算全数据集整体MAPE的时候才需要做求平均操作。
修复方案
方案1:逐行计算每行MAPE(匹配你生成MAPE_Mar列的需求)
先修正MAPE函数的逻辑,再调整apply的传参方式即可:
# 修正后的逐行MAPE计算函数 def mape(actual, pred): if actual == 0: return 0 if pred == 0 else 100 else: return np.abs((actual - pred) / actual) * 100 # 正确的apply调用写法,x代表当前行,取当前行的两列值传入函数 df['MAPE_Mar'] = df.apply(lambda x: mape(x['Actuals_March'], x['Forecast_March']), axis=1)
方案2:计算全数据集整体MAPE(如果不需要逐行结果,直接求整体值的更高效写法)
不需要调用apply,直接用向量化运算即可,性能远高于逐行遍历:
def overall_mape(actual_series, pred_series): # 标记actual为0的行 zero_mask = actual_series == 0 error = np.zeros_like(actual_series, dtype=np.float64) # 处理actual为0的行的误差 error[zero_mask] = np.where(pred_series[zero_mask] == 0, 0, 100) # 处理actual不为0的行的误差 error[~zero_mask] = np.abs((actual_series[~zero_mask] - pred_series[~zero_mask]) / actual_series[~zero_mask]) * 100 return np.mean(error) # 直接传入两列数据得到整体MAPE total_mape = overall_mape(df['Actuals_March'], df['Forecast_March'])
内容的提问来源于stack exchange,提问作者R overflow
相关产品推荐
相关产品推荐

