编写IQR法移除异常值Python函数,执行后箱线图仍显示异常值,如何排查?
代码问题排查与修正
核心问题
你的代码存在3个主要问题,是异常值未被删除的核心原因:
- 函数无返回值:你在函数内部操作的
data是局部变量,没有添加return data语句返回处理结果,调用函数时如果没有将返回值赋值给变量,原始数据集不会发生任何修改,你绘制箱线图使用的仍是原始数据,自然会看到异常值残留。 - 逐列过滤逻辑偏差:当前代码每删除一列的异常值后,后续列计算四分位数(Q1、Q3)时使用的是已经被裁剪过的数据集,而非原始数据集,判断异常值的标准会不断偏移,导致大量原本符合异常值判定规则的数据被保留。
- 非数值列被丢弃:函数开头直接将
data替换为仅包含数值类型的子集,原数据中的非数值列会全部丢失,如果你校验时使用的是完整原始数据集对比,也会出现结果不一致的问题。
修正后的代码
import pandas as pd def remove_outliers(data): # 筛选数值列 numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64'] numeric_data = data.select_dtypes(include=numerics) # 初始化全为True的掩码,代表默认保留所有行 keep_mask = pd.Series([True] * len(data), index=data.index) for col in numeric_data.columns: Q1 = numeric_data[col].quantile(0.25) Q3 = numeric_data[col].quantile(0.75) IQR = Q3 - Q1 # 计算当前列需要保留的行的掩码 col_keep_mask = ~((numeric_data[col] < (Q1 - 1.5 * IQR)) | (numeric_data[col] > (Q3 + 1.5 * IQR))) # 合并掩码:只有所有列都判定为正常的行才会被保留 keep_mask &= col_keep_mask # 返回过滤后的完整数据集,保留所有原始列 return data[keep_mask]
调用注意事项
调用函数时需要将返回值赋值给变量,才会得到处理后的数据集:
# 正确调用方式 processed_df = remove_outliers(raw_df) # 错误调用方式,原始数据不会被修改 remove_outliers(raw_df)
内容的提问来源于stack exchange,提问作者Insan Cahya
相关产品推荐
相关产品推荐

