Python处理异常值outliers检测与处理教程
用箱线图IQR法和3σ标准差法检测数据中的异常值,提供删除、截断、替换三种处理方式,适合销售数据、工资数据的清洗。
场景痛点
业务报表里突然冒出来一笔100万的订单,或者员工工资表混进一个1000万的样本,不处理的话平均值被拉飞,领导看了报表要骂。手动一个个找异常值眼睛花,用IQR箱线图法和3σ法自动识别,再决定删除还是截断,几分钟搞定。
用到的库
pip install pandas numpy
完整代码
import pandas as pd
import numpy as np
def sample_df():
return pd.DataFrame({
"name": ["甲", "乙", "丙", "丁", "戊", "己", "庚", "辛"],
"salary": [12000, 15000, 13000, 14000, 12500, 16000, 11000, 90000],
})
def iqr_method(s: pd.Series):
"""IQR箱线图法:超出 [Q1-1.5*IQR, Q3+1.5*IQR] 视为异常"""
q1 = s.quantile(0.25)
q3 = s.quantile(0.75)
iqr = q3 - q1
low, high = q1 - 1.5 * iqr, q3 + 1.5 * iqr
mask = (s < low) | (s > high)
return mask, low, high
def sigma_method(s: pd.Series):
"""3σ法:偏离均值3个标准差之外视为异常"""
mean = s.mean()
std = s.std()
low, high = mean - 3 * std, mean + 3 * std
mask = (s < low) | (s > high)
return mask, low, high
def outliers_demo():
df = sample_df()
print("原始:")
print(df)
# IQR法
mask_iqr, low, high = iqr_method(df["salary"])
print(f"\nIQR法阈值:[{low:.0f}, {high:.0f}]")
print("异常值:")
print(df[mask_iqr])
# 处理方式1:直接删除
df_clean = df[~mask_iqr].copy()
print(f"\n删除异常值后剩余 {len(df_clean)} 行")
# 处理方式2:截断到上下限(winsorize)
df["salary_winsor"] = df["salary"].clip(lower=low, upper=high)
print("\n截断处理后:")
print(df)
# 处理方式3:用中位数替换
median = df["salary"].median()
df.loc[mask_iqr, "salary_median"] = median
df.loc[~mask_iqr, "salary_median"] = df["salary"]
print("\n中位数替换后:")
print(df[["name", "salary", "salary_median"]])
if __name__ == "__main__":
outliers_demo()
代码讲解
- IQR法:Q1是25%分位数,Q3是75%分位数,IQR=Q3-Q1。异常值定义为小于Q1-1.5IQR或大于Q3+1.5IQR,对偏态分布(如收入)很稳健。
- 3σ法:正态分布下99.7%的数据落在±3σ内,适合近似正态的数据。工资、销售额通常右偏,IQR更合适。
- 三种处理:删除
df[~mask]最简单;clip(lower, upper)截断到边界,保留样本量;中位数替换适合异常比例不高的情况。 - 处理前先
df[mask]看一眼具体是哪些行,确认是真异常还是业务极值(比如大客户),别误删。
运行结果
控制台打印原始8行数据,其中辛的90000是异常值。IQR法识别出辛为异常,删除后剩7行;截断后辛的工资被压到上限;中位数替换后辛的工资换成中位数13250。
注意事项
- 异常值不一定是错的:90000可能是CEO真实工资,业务上要保留,统计分析时才处理。
- 同一列不同业务线分布不同,应分组检测:
df.groupby("dept")["salary"].apply(...)分别识别。 - 客户金额、订单量这类对数正态分布数据,先
np.log()再检测异常值更合理。 - 处理完要把原始列和处理后列都保留,方便回溯。

更新时间:2026-09-14 20:58:27
上一篇:Python pandas apply自定义函数教程