You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 13:45:16