Z-Score过滤需先检验目标列正态性,再单独计算Z-Score(axis=0、nan_policy='omit'),阈值2.5或3应结合样本量与分布偏斜程度选择,避免直接对原始数据取abs(z)>3误删。

用 scipy.stats.zscore 做 Z-Score 过滤,别直接用绝对值阈值
Z-Score 本身不等于“是否离群”,它只是标准化后的偏离程度;直接对原始数据算 zscore 再取 abs(z) > 3 很容易误删——尤其当数据分布偏斜或含大量零值时。
真正该做的是:先确认目标列近似正态(比如画个直方图或看 scipy.stats.shapiro 的 p 值),再对 该列单独 计算 Z-Score:
– 用 axis=0 防止跨行广播出错
– 用 nan_policy='omit' 避免 NaN 搞崩整个向量
– 阈值选 2.5 或 3 要结合样本量:n
IQR 方法里 np.percentile 的 q 参数别写错顺序
IQR 不依赖分布假设,但实现时很多人把四分位数搞反:Q1 是 25% 分位,Q3 是 75%,不是反过来。用 np.percentile(data, [25, 75]) 最稳,别手敲 q=0.25 和 q=0.75 却漏掉括号导致返回单个标量。
– 边界计算必须用 Q1 - 1.5 * IQR 和 Q3 + 1.5 * IQR,系数 1.5 是经验常数,不能替换成 2 或 3
– 如果数据里有大量重复值(比如传感器采样中的平台值),IQR 可能为 0,这时直接用 == 0 判断并跳过过滤,否则会误删整列
– 多列同时处理时,axis=0 必须显式指定,否则默认按扁平数组算
Pandas 中用 df.loc 索引过滤比布尔索引更安全
直接写 df[~is_outlier] 看似简洁,但当 is_outlier 是用 apply 生成、长度和 df.index 不一致时,Pandas 会静默对齐——结果可能删掉错的行。
– 正确做法是构造与原 df 行数一致的布尔 Series,索引完全匹配
– 推荐用 df.loc[~is_outlier],哪怕 is_outlier 是 numpy array,Pandas 也会强制按位置对齐
– 如果用了 groupby 后逐组过滤,记得在 apply 里返回带原索引的布尔值,别用 reset_index(drop=True) 断掉关联
离群点不是错误,删之前得看业务逻辑是否允许
传感器故障、用户误操作、系统抖动……这些确实该剔除;但金融交易里的大额单、电商促销日的峰值流量,本身就是关键信号。
– 先用 plt.boxplot 或 sns.boxplot 看离群点在什么区间、有多少个、是否成簇出现
– 对时间序列,别用全局 IQR,改用滑动窗口(如 df['x'].rolling(30).apply(lambda x: np.percentile(x, 75) - np.percentile(x, 25)))
– 如果后续要建模,建议保留离群标记列(如 is_outlier_z、is_outlier_iqr),而不是直接丢弃——有些模型能学出“异常模式”
立即学习“Python免费学习笔记(深入)”;










