为什么以下Python异常值检测代码运行后返回空列表?
代码存在的问题及修正方案
核心问题梳理
- 1. 未导入依赖函数导致报错
代码中直接使用了floor函数,但未导入math模块,运行时会直接抛出NameError: name 'floor' is not defined错误。 - 2. 四分位数计算逻辑完全错误
四分位数(Q1/Q3)是对原始排序后的数据集拆分计算得到的分位值,而非对「最小值到中位数的连续整数范围」「中位数到最大值的连续整数范围」求中位数。你当前的实现存在两个致命问题:- 用
range生成整数范围的逻辑完全不符合四分位数定义,得到的Q3值会被异常值100000000拉到极大,导致IQR(四分位距)计算结果异常偏大 - 当数据集存在超大异常值时,
range(floor(median(args)),fmax(args)+1)生成的序列长度极大,转list时会占用极高内存甚至触发内存溢出
- 用
- 3. 异常值判定公式书写错误
标准的箱线图异常值判定规则为:异常值 < Q1 - 1.5IQR 或 异常值 > Q3 + 1.5IQR,你代码中多乘了一次(q3-q1),相当于把上阈值放大了IQR倍,导致即便是100000000也达不到阈值,所以始终返回空列表。
修正后的可运行代码
import math def outlier(*args): outlist = [] sorted_data = sorted(args) n = len(sorted_data) # 计算中位数的通用函数 def median(data_subset): m = len(data_subset) mid = m // 2 if m % 2 == 1: return data_subset[mid] else: return (data_subset[mid-1] + data_subset[mid]) / 2 # 正确计算Q1、Q3、IQR mid = n // 2 if n % 2 == 1: q1 = median(sorted_data[:mid]) q3 = median(sorted_data[mid+1:]) else: q1 = median(sorted_data[:mid]) q3 = median(sorted_data[mid:]) iqr = q3 - q1 # 正确的异常值判定 lower_bound = q1 - 1.5 * iqr upper_bound = q3 + 1.5 * iqr for i in args: if i < lower_bound or i > upper_bound: outlist.append(i) return outlist print(outlier(1,2,3,4,5,6,7,8,9,10,100000000)) # 输出结果:[100000000]
内容的提问来源于stack exchange,提问作者user16377193
相关产品推荐
相关产品推荐

