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

含数值与字符串列的大数据集异常值过滤问题求助

修正批量IQR异常值过滤的逻辑错误

你的代码核心问题是每次计算异常值时都基于原始数据集df,而非逐步过滤后的df_filtered。这会导致:即使某一行已经被前一列的过滤逻辑删除,后续列仍会把原始数据中该行的异常标记出来,重复执行删除操作,最终导致过度过滤。

修正后的代码

import numpy as np
import pandas as pd

def filter_outliers(df):
    numeric_columns = df.select_dtypes(include=[np.number]).columns
    df_filtered = df.copy()
    
    for column in numeric_columns:
        # 基于当前过滤后的数据集计算IQR边界
        q1 = df_filtered[column].quantile(0.25)
        q3 = df_filtered[column].quantile(0.75)
        iqr = q3 - q1
        lower_bound = q1 - 1.5 * iqr
        upper_bound = q3 + 1.5 * iqr
        
        # 定位当前数据集中的异常值并过滤
        outlier_mask = (df_filtered[column] < lower_bound) | (df_filtered[column] > upper_bound)
        df_filtered = df_filtered[~outlier_mask]
    
    return df_filtered

关键改动说明

  • 所有统计量(q1、q3、iqr)的计算都改用df_filtered,确保每一步的异常值判断都是基于当前已清理的数据
  • 直接用布尔掩码过滤行,比先找异常索引再drop更高效,也避免索引处理的潜在问题

可选优化:一次性收集所有异常索引(适合大数据集)

如果数据集规模较大,循环多次修改DataFrame效率较低,可以先收集所有需要删除的行标记,最后一次性过滤:

def filter_outliers(df):
    numeric_columns = df.select_dtypes(include=[np.number]).columns
    # 初始化全True掩码,标记需要保留的行
    keep_mask = pd.Series([True] * len(df), index=df.index)
    
    for column in numeric_columns:
        q1 = df[column].quantile(0.25)
        q3 = df[column].quantile(0.75)
        iqr = q3 - q1
        lower_bound = q1 - 1.5 * iqr
        upper_bound = q3 + 1.5 * iqr
        
        # 更新保留掩码:仅保留当前列非异常的行
        column_keep_mask = (df[column] >= lower_bound) & (df[column] <= upper_bound)
        keep_mask = keep_mask & column_keep_mask
    
    # 一次性过滤所有行
    return df[keep_mask]

这种方式的逻辑是:只要某一行在任意一个数值列中是异常值,就被标记为删除,最终只保留所有数值列都无异常的行,和循环过滤结果一致,但执行效率更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 03:35:04