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

如何保留目标变量值为1的行,同时过滤其他行的异常值?

不平衡数据集的异常值过滤需求

我有一个包含30个预测变量和1个目标变量的大型不平衡数据集:280,000条数据的目标值为false,仅450条为true。我需要基于这30个预测变量过滤异常值,但必须保留所有目标值为true(Class=1)的行。


当前尝试的代码

异常值检测与移除函数

def detect_outlier(df_in, col_name):
    for row in df_in['Class']:
        if row != 1:
            q1 = df_in[col_name].quantile(0.25)
            q3 = df_in[col_name].quantile(0.75)
            iqr = q3-q1
            fence_low  = q1-1.5*iqr
            fence_high = q3+1.5*iqr
            df_out = df_in.index[(df_in[col_name] > fence_low) & (df_in[col_name] < fence_high)]
            return df_out

def remove(df, ls):
    ls = sorted(set(ls))
    df = df.drop(ls)
    return df

def remove(df, ls):
    ls = sorted(set(ls))
    df = df.drop(ls)
    return df

调用代码

# 检测Amount列的异常值
list = detect_outlier(cc_df,'Amount')
list

# 移除异常值得到新数据集
cc_df2 = remove(cc_df,list)
cc_df2

现有代码的问题

  1. 异常值检测逻辑完全错误:
    • 循环遍历Class列时,遇到第一个Class≠1的行就直接计算全量数据的IQR区间并返回,既没有针对Class≠1的子集处理,也没实现保留Class=1行的要求。
    • 计算分位数用了整个数据集,会被少数Class=1的样本干扰异常值判断。
    • 返回的是正常行的索引,但后续删除操作会把正常行删掉,完全搞反了逻辑。
  2. 冗余代码:重复定义了两次remove函数,无意义。
  3. 变量名不规范:使用Python内置类型list作为变量名,容易引发冲突。

改进后的实现方案

核心思路:仅对Class≠1的子集计算异常值,标记需要删除的异常行索引,最终保留Class=1的所有行 + Class≠1中的非异常行。

def detect_outliers_by_class(df, col_name, target_col='Class', target_keep=1):
    # 分离需要保留的行和需要检测异常的行
    keep_df = df[df[target_col] == target_keep]
    check_df = df[df[target_col] != target_keep]
    
    # 仅基于待检测子集计算IQR区间
    q1 = check_df[col_name].quantile(0.25)
    q3 = check_df[col_name].quantile(0.75)
    iqr = q3 - q1
    fence_low = q1 - 1.5 * iqr
    fence_high = q3 + 1.5 * iqr
    
    # 找出待检测子集中的异常行索引
    outlier_indices = check_df[(check_df[col_name] <= fence_low) | (check_df[col_name] >= fence_high)].index
    
    return outlier_indices

def remove_outliers(df, outlier_indices):
    # 删除异常行,自动保留所有Class=1的行
    cleaned_df = df.drop(outlier_indices)
    return cleaned_df

# 单列处理示例(比如Amount列)
outlier_idx = detect_outliers_by_class(cc_df, 'Amount')
cc_df_cleaned = remove_outliers(cc_df, outlier_idx)

# 批量处理30个预测变量示例
# 先定义所有预测变量列名(假设排除目标列Class)
# predictor_cols = [col for col in cc_df.columns if col != 'Class']
# all_outlier_idx = []
# for col in predictor_cols:
#     col_outliers = detect_outliers_by_class(cc_df, col)
#     all_outlier_idx.extend(col_outliers)
# # 去重后删除所有异常行
# all_outlier_idx = list(set(all_outlier_idx))
# cc_df_cleaned_all = remove_outliers(cc_df, all_outlier_idx)

改进点说明

  • 精准过滤:仅针对Class≠1的样本计算异常值,避免少数正样本干扰判断。
  • 逻辑正确:返回需要删除的异常行索引,确保所有Class=1的行被完整保留。
  • 可扩展性:支持单列处理,也能批量遍历所有30个预测变量完成全局异常值过滤。
  • 代码规范:移除冗余函数,避免使用内置类型作为变量名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 02:25:23