用 numpy.percentile 计算 IQR 更可控准确:Q1=np.percentile(df[col],25),Q3=np.percentile(df[col],75),上下界为 Q1−1.5×IQR 和 Q3+1.5×IQR,注意括号优先级;过滤时拆分布尔索引,避免掩码错位。

用 numpy.percentile 做 IQR 法检测最稳
直接用 pandas.DataFrame.describe() 看四分位数容易漏掉边缘异常点,而手算 IQR(四分位距)配合 numpy.percentile 更可控、更准。关键是把上下界计算和布尔索引拆开,避免链式调用导致掩码错位。
-
Q1 = np.percentile(df[col], 25)和Q3 = np.percentile(df[col], 75)比df[col].quantile(0.25)在含NaN时行为更一致(默认跳过NaN) - 上下界建议用
Q1 - 1.5 * (Q3 - Q1)和Q3 + 1.5 * (Q3 - Q1),别省略括号,否则乘法优先级会出错 - 过滤时用
df[(df[col] >= lower_bound) & (df[col] ,必须用 <code>&而不是and,否则报ValueError: The truth value of a Series is ambiguous
对多列批量处理要避开 apply 的隐式类型转换
用 df.select_dtypes(include=['number']) 先捞出数值列,再逐列处理——别图省事写 df.apply(lambda x: ...),它会强制把整行转成 object dtype,导致 np.percentile 报 TypeError: cannot perform reduce with flexible type。
- 推荐用
for col in numeric_cols:显式循环,每列独立算 IQR,保留原始 dtype - 如果想一行过滤全表,构建布尔掩码时用
mask = pd.Series([True] * len(df))初始化,再对每列做mask &= (df[col] >= lb) & (df[col] - 注意:
select_dtypes不识别Int64(pandas nullable int),需额外加include=['number', 'Int64']
scipy.stats.zscore 适合正态分布数据,但别无脑设阈值 3
Z-score 方法快,但前提是数据近似正态。实际中很多业务指标(比如订单金额、响应时长)右偏严重,直接用 abs(zscore) > 3 会误杀大量正常高值。
安全 Python 代码沙箱:在隔离的沙箱中执行任意 Python 代码,预装 requests、NumPy、pandas 库。返回 stdout、stderr。
- 先用
scipy.stats.shapiro或直方图快速扫一眼分布形态,不满足正态就换 IQR -
zscore默认按列计算,但若 DataFrame 有NaN,得显式传nan_policy='omit',否则返回全nan - 阈值不一定要是 3:对小样本(
n ),用 <code>2.5更稳妥;对监控类场景,可动态取np.percentile(abs(z), 99)当上限
过滤后记得检查空值和 dtype 回退
异常值替换成 np.nan 后,int 列会自动转成 float64,后续 merge 或写入数据库可能报错;直接删行则要防 df.empty 导致下游 KeyError。
- 替换异常值后,用
df[col] = df[col].astype('Int64')(pandas 专用)或df[col].convert_dtypes()尝试恢复整型 - 删除行前加
if not mask.all(): df = df[mask],避免空 DataFrame - 别忽略
pd.options.mode.chained_assignment = None,否则df.loc[mask, col] = np.nan可能触发 SettingWithCopyWarning 且不生效
IQR 法在大多数业务场景下比 Z-score 更鲁棒,但真正麻烦的不是算法本身,而是数值列里混着 inf、字符串型数字(如 '12.5')、或不同单位混存(比如有的字段是毫秒有的是秒)——这些得在检测前用 pd.to_numeric(..., errors='coerce') 统一清理。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










