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

使用百分位数去除Pandas DataFrame异常值时遇逻辑问题求助

解决Pandas中用百分位数去除异常值时的逻辑问题

嘿,我猜你遇到的逻辑问题大概率是处理完特征列后没法关联回原有的id和label,或者是训练集/测试集的过滤逻辑不一致导致的数据泄露——毕竟你同时传入了训练和测试数据,这两个点是新手用百分位过滤异常值时最容易踩的坑。我来帮你把代码捋顺并修正:

修正后的完整代码

def processing_data(train_data, test_data):
    # 第一步:明确要处理的特征列(排除id和label)
    feature_cols = train_data.columns.drop(['id', 'label'])
    
    # 第二步:仅用训练集计算百分位数(核心!避免测试集数据泄露)
    low_percentile = 0.05
    high_percentile = 0.95
    quantile_bounds = train_data[feature_cols].quantile([low_percentile, high_percentile])
    
    # 第三步:定义通用过滤函数,保留所有特征在百分位区间内的样本
    def filter_outliers(df):
        # 对每个特征生成「是否在区间内」的布尔掩码
        feature_mask = df[feature_cols].apply(
            lambda col: col.between(
                quantile_bounds.loc[low_percentile, col.name],
                quantile_bounds.loc[high_percentile, col.name]
            ),
            axis=0
        )
        # 要求样本的所有特征都符合条件(行内全为True才保留)
        final_mask = feature_mask.all(axis=1)
        # 返回包含id和label的完整过滤后数据
        return df[final_mask]
    
    # 第四步:分别过滤训练集和测试集
    cleaned_train = filter_outliers(train_data)
    cleaned_test = filter_outliers(test_data)
    
    return cleaned_train, cleaned_test

关键逻辑说明(帮你避开之前的坑)

  • 不提前移除id/label:直接在原数据框上用掩码过滤,这样id和label会自动和过滤后的特征列对应,不会丢失关联关系。之前你先移除这两列再处理,很容易导致后续无法把标识列加回去。
  • 训练集单独计算百分位:绝对不能用测试集的数据参与百分位数计算,否则属于数据泄露——测试集必须完全模拟真实场景,用训练集学到的规则来过滤。
  • 逐特征校验+全特征达标:apply会对每个特征单独判断是否在区间内,all(axis=1)确保只有所有特征都正常的样本才被保留(如果你的业务允许单个特征异常的样本保留,可以把all改成any,但一般异常值过滤都是要求全特征正常)。

额外的优化建议

  • 如果某些特征不需要过滤异常值,可以在feature_cols里手动排除它们,比如feature_cols = train_data.columns.drop(['id', 'label', '不需要过滤的列名'])
  • 百分位数阈值可以根据业务调整:如果0.05/0.95去掉的数据太多,试试0.01/0.99;如果还是有异常值,可以考虑用四分位距(IQR)方法结合百分位使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:27:14