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

自定义异常值移除函数未完全清理异常值且后续调用报KeyError问题

解决KNN填充后逐列移除异常值的KeyError与未完全删除问题

问题根源分析

  1. KeyError 原因:
    你用np.where拿到的是数据的整数位置索引,但pd.DataFrame.drop()默认按标签索引删除行。第一次调用函数处理ph列后,non_null_rows的行标签已不连续(部分行被删除),此时用原位置对应的标签去删除,就会出现找不到索引的错误(比如2189行已被删掉)。
  2. 异常值未完全移除:
    函数中先删upper异常值再删lower,但删除upper后数据集已变化,而lower的索引仍基于原数据集计算,导致部分lower异常值未被正确识别删除。

修复后的函数代码

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd

def remove_outliers(dataset, col_name, raw_data):
    # 计算IQR上下界
    Q1 = dataset[col_name].quantile(0.25)
    Q3 = dataset[col_name].quantile(0.75)
    IQR = Q3 - Q1
    lower_bound = Q1 - 1.5 * IQR
    upper_bound = Q3 + 1.5 * IQR

    # 布尔索引一次性筛选正常数据,避免索引混乱
    mask = (dataset[col_name] >= lower_bound) & (dataset[col_name] <= upper_bound)
    cleaned_dataset = dataset[mask].copy()
    cleaned_dataset = cleaned_dataset.reset_index(drop=True)

    # 绘制箱线图对比
    plt.figure(figsize=(10, 0.5))
    sns.boxplot(raw_data[col_name], orient="h").set(xlabel=f"{col_name} raw data")
    plt.show()

    plt.figure(figsize=(10, 0.5))
    sns.boxplot(cleaned_dataset[col_name], orient="h").set(xlabel=f"{col_name} no outliers")
    plt.show()

    return cleaned_dataset

改动说明

  • 用布尔掩码一次性筛选:避免分两次drop导致的索引不匹配,确保异常值被完整过滤。
  • 传入原始数据集raw_data绘图:避免依赖全局变量,函数逻辑更独立。
  • 提前copy()数据集:避免对原数据集的意外修改,保证每轮处理的独立性。

调用方式

# 处理ph列
non_null_rows = remove_outliers(non_null_rows, 'ph', H2O_data)
# 处理Hardness列
non_null_rows = remove_outliers(non_null_rows, 'Hardness', H2O_data)

这样调用后,既不会触发KeyError,也能完整移除每列的异常值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 12:15:32