如何用Python编写while循环迭代Winsorize直至age变量无异常值
迭代寻找无异常值的截尾比例
原始代码
用户提供的初始代码:
from scipy.stats.mstats import winsorize import pandas as pd # winsorize function def winsor_try1(var, lower, upper): var = winsorize(var,limits=[lower,upper]) ''' Outliers Calculation using IQR ''' q1, q3= np.percentile(var, [25, 75]) # q1,q3 calc iqr = q3 - q1 # iqr calc lower_bound = round(q1 - (1.5 * iqr),3) # lower bound upper_bound = round(q3 + (1.5 * iqr),3) # upper bound outliers = [x for x in var if x < lower_bound or x > upper_bound] print('These would be the outliers:', set(outliers),' ', 'Total:', len(outliers),'.Upper bound & Lower bound:', lower_bound,'&',upper_bound) # the variable df = pd.DataFrame({ 'age': [1,1,2,5,5,2,5,4,8,2,5,1,41,2,1,4,4,1,1,4,1,2,15,21,5,1,8,22,1,5,2,5,256,5,6,2,2,8,452]})
需求说明
需要实现一个while循环,从lower = 0.01、upper = 0.01开始,重复调用winsor_try1处理df['age'],直到异常值数量为0,最终输出对应的截尾比例。
解决方案
首先修正原代码的两处问题:
- 缺失
numpy导入(代码中用到了np.percentile) winsor_try1函数无返回值,无法在循环中判断异常值状态
修改后的完整可运行代码如下:
from scipy.stats.mstats import winsorize import pandas as pd import numpy as np # 补全缺失的numpy导入 # 修改后的winsorize函数,返回异常值数量供循环判断 def winsor_try1(var, lower, upper): var = winsorize(var, limits=[lower, upper]) # IQR法计算异常值 q1, q3 = np.percentile(var, [25, 75]) iqr = q3 - q1 lower_bound = round(q1 - (1.5 * iqr), 3) upper_bound = round(q3 + (1.5 * iqr), 3) outliers = [x for x in var if x < lower_bound or x > upper_bound] print(f"当前截尾比例: {lower:.2f}") print(f"异常值集合: {set(outliers)}") print(f"异常值总数: {len(outliers)} | 上下界: {lower_bound} & {upper_bound}\n") return len(outliers) # 返回异常值数量 # 初始化数据 df = pd.DataFrame({ 'age': [1,1,2,5,5,2,5,4,8,2,5,1,41,2,1,4,4,1,1,4,1,2,15,21,5,1,8,22,1,5,2,5,256,5,6,2,2,8,452]}) # 初始化截尾参数 current_limit = 0.01 step = 0.01 # 每次迭代的步长,可按需调整 max_limit = 0.5 # 设置最大截尾比例,避免无限循环 # 迭代寻找无异常值的截尾比例 while current_limit <= max_limit: outlier_count = winsor_try1(df['age'], current_limit, current_limit) if outlier_count == 0: print(f'At limit = {current_limit:.2f}, there is no more outliers presented in the age variable.') break current_limit += step else: print(f"已达到最大截尾比例{max_limit:.2f},仍存在异常值")
代码关键点说明
- 补全依赖导入:添加
numpy导入,确保分位数计算正常运行 - 函数返回值优化:让
winsor_try1返回异常值数量,方便循环判断终止条件 - 循环逻辑设计:从0.01开始逐步递增截尾比例,直到异常值为0
- 安全限制:设置最大截尾比例(0.5),防止极端情况下出现无限循环
内容的提问来源于stack exchange,提问作者Minh Chau
相关产品推荐
相关产品推荐

