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

循环迭代移除DataFrame异常值问题求助

迭代移除DataFrame异常值的逻辑问题

我有一个DataFrame,需要循环迭代提取并移除其中的异常值:每次移除异常值后重新检查新的DataFrame,若仍存在异常值则继续移除,以此类推。但目前仅能移除首次出现的异常值,无法将后续异常值与之前的合并后从原始数据中一并移除,代码逻辑肯定有问题。

原始DataFrame:

import pandas as pd
df = pd.DataFrame({'Date':
      ['01-01-2022','02-01-2022','03-01-2022','04-01-2022','05-01-2022','06-01-2022','07-01-2022','08-01-2022','09-01-2022','10-01-2022','11-01-2022','12-01-2022','13-01-2022','14-01-2022','15-01-2022','16-01-2022','17-01-2022','18-01-2022','19-01-2022','20-01-2022'],
     'Value':
      [100,50,60,3,85,15,250,97,150,25,49,64,88,35,154,73,67,48,52,90]})

预期效果:

  • 第一次循环排除第6行(值:250)
  • 第二次循环排除第8行(值:150)和第14行(值:154)
  • 最终得到无异常值的DataFrame

使用的代码:

outlier = []
df2 = []
    
while True:
    Q1 = df['Value'].quantile(0.25)
    Q3 = df['Value'].quantile(0.75)
    IQR = Q3 - Q1
    Lower_Limit = Q1 - 1.5 * IQR
    Upper_Limit = Q3 + 1.5 * IQR

    outliers = df['Value'][((df['Value'] < Lower_Limit)|(df['Value'] > Upper_Limit))]
    outlier.append(outliers)
    df = df['Value'][~((df['Value'] < Lower_Limit)|(df['Value'] > Upper_Limit))]
    df2.append(df)
    
    Q1 = pd.DataFrame(df2).quantile(0.25)
    Q3 = pd.DataFrame(df2).quantile(0.75)
    IQR = Q3 - Q1
    Lower_Limit = Q1 - 1.5 * IQR
    Upper_Limit = Q3 + 1.5 * IQR

    outliers = pd.DataFrame(df2)[((pd.DataFrame(df2) < Lower_Limit) | (pd.DataFrame(df2) > Upper_Limit))].dropna()
    outlier.append(outliers)
    df2 = pd.DataFrame(df2)[~((pd.DataFrame(df2) < Lower_Limit) |(pd.DataFrame(df2) > Upper_Limit))]
    df2.append(df2)
    break

当前输出:

print('df before Removing Outliers: ' + str(len(df)))
print('df After Removing Outliers: ' + str(len(df2)))
print('Number of outliers: ' + str(len(outlier)))
print('Max outlier value: '+ str(outlier.max()))
print('Min outlier value: '+ str(outlier.min()))

# 输出结果
df before Removing Outliers: 20
df After Removing Outliers: 17
Number of outliers: 3
Max outlier value: 250
Min outlier value: 150

问题分析与修复代码

原代码核心问题

  1. 循环逻辑失效:while True仅执行一次就break,完全没实现迭代检查;中途把df转成Series,丢失了Date列和原始索引,无法准确追踪异常值。
  2. 数据结构混乱:df2初始为列表,中途强行转DataFrame,导致数据格式错乱,无法正确迭代更新。
  3. 异常值收集逻辑错误:重复计算IQR且逻辑重叠,异常值未按原始数据统一归集。

修复后的代码

import pandas as pd

# 原始数据
df = pd.DataFrame({'Date':
      ['01-01-2022','02-01-2022','03-01-2022','04-01-2022','05-01-2022','06-01-2022','07-01-2022','08-01-2022','09-01-2022','10-01-2022','11-01-2022','12-01-2022','13-01-2022','14-01-2022','15-01-2022','16-01-2022','17-01-2022','18-01-2022','19-01-2022','20-01-2022'],
     'Value':
      [100,50,60,3,85,15,250,97,150,25,49,64,88,35,154,73,67,48,52,90]})

# 保留原始数据副本,用于最终移除所有异常值
original_df = df.copy()
all_outliers = pd.DataFrame(columns=df.columns)

while True:
    # 计算当前DataFrame的IQR和上下限
    Q1 = df['Value'].quantile(0.25)
    Q3 = df['Value'].quantile(0.75)
    IQR = Q3 - Q1
    lower_limit = Q1 - 1.5 * IQR
    upper_limit = Q3 + 1.5 * IQR
    
    # 找出当前的异常值
    current_outliers = df[(df['Value'] < lower_limit) | (df['Value'] > upper_limit)]
    
    # 如果没有异常值,终止循环
    if current_outliers.empty:
        break
    
    # 收集异常值
    all_outliers = pd.concat([all_outliers, current_outliers])
    # 移除当前异常值,更新DataFrame
    df = df[~((df['Value'] < lower_limit) | (df['Value'] > upper_limit))]

# 从原始数据中移除所有收集到的异常值
final_df = original_df[~original_df.index.isin(all_outliers.index)]

# 打印结果
print('原始数据行数: ' + str(len(original_df)))
print('移除异常值后行数: ' + str(len(final_df)))
print('异常值总数: ' + str(len(all_outliers)))
print('异常值最大值: '+ str(all_outliers['Value'].max()))
print('异常值最小值: '+ str(all_outliers['Value'].min()))
print('\n所有异常值:')
print(all_outliers)
print('\n最终无异常值的DataFrame:')
print(final_df)

修复后效果

  • 第一次循环识别并收集值为250的异常行
  • 第二次循环更新IQR后,识别并收集值为150和154的异常行
  • 第三次循环检查无异常值,终止循环
  • 最终从原始数据中一次性移除所有异常值,保留完整的Date列和正确数据结构

内容的提问来源于stack exchange,提问作者Mahmoud Badr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 08:10:28