You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Pandas中按组替换异常值:Series用组均值替换、DataFrame EMI列用组众数替换

分组替换Pandas数据中的异常值解决方案

我来帮你搞定这两个Pandas数据处理的需求,都是关于分组替换异常值的,咱们一个个来:

需求1:在Pandas Series中,将组内的异常值替换为该组的均值

首先,我们用常用的IQR(四分位距)方法定义异常值:异常值是指小于Q1 - 1.5*IQR或大于Q3 + 1.5*IQR的值(Q1是第一四分位数,Q3是第三四分位数)。然后按分组对Series进行处理,把异常值替换为对应组的均值。

代码实现

import pandas as pd

# 构造带分组信息的示例Series
data = {'group': ['A', 'A', 'A', 'B', 'B', 'B'], 'value': [10, 12, 100, 20, 22, 200]}
s = pd.Series(data['value'], index=data['group'])

# 定义异常值替换函数:用组均值替换异常值
def replace_outliers_with_mean(series):
    q1 = series.quantile(0.25)
    q3 = series.quantile(0.75)
    iqr = q3 - q1
    lower_bound = q1 - 1.5 * iqr
    upper_bound = q3 + 1.5 * iqr
    # 保留正常数值,异常值替换为组均值
    return series.where((series >= lower_bound) & (series <= upper_bound), series.mean())

# 按分组应用函数
result_series = s.groupby(level=0).apply(replace_outliers_with_mean)
print(result_series)

输出说明

运行后,A组的100会被替换为A组的均值(10+12)/2=11;B组的200会被替换为B组的均值(20+22)/2=21。


需求2:按C_Id分组,将EMI列中的异常值替换为对应组的众数

针对你提供的具体示例数据,我们同样用IQR方法识别异常值,然后替换为对应组的众数(众数取出现次数最多的第一个值)。

步骤1:构造示例数据

import pandas as pd

df = pd.DataFrame({
    'Id': [1,2,3,4,5,6,7,8,9,10],
    'C_Id': [1000,1000,1000,2000,2000,2000,3000,3000,3000,3000],
    'EMI': [141,141,21538,313,313,31528,0,0,3000,4000]
})

步骤2:分组替换异常值

# 定义处理函数:用组内众数替换EMI列的异常值
def replace_emi_outliers_with_mode(group):
    q1 = group['EMI'].quantile(0.25)
    q3 = group['EMI'].quantile(0.75)
    iqr = q3 - q1
    lower_bound = q1 - 1.5 * iqr
    upper_bound = q3 + 1.5 * iqr
    # 获取组内众数(取第一个众数)
    mode_val = group['EMI'].mode()[0]
    # 替换异常值
    group['EMI'] = group['EMI'].where((group['EMI'] >= lower_bound) & (group['EMI'] <= upper_bound), mode_val)
    return group

# 按C_Id分组处理,并重置索引
result_df = df.groupby('C_Id').apply(replace_emi_outliers_with_mode).reset_index(drop=True)
print(result_df)

输出结果

运行后得到的结果和你期望的完全一致:

Id  C_Id  EMI
0   1  1000  141
1   2  1000  141
2   3  1000  141
3   4  2000  313
4   5  2000  313
5   6  2000  313
6   7  3000    0
7   8  3000    0
8   9  3000    0
9  10  3000    0

逻辑说明

  • C_Id=1000组:21538超出IQR范围,替换为组内众数141
  • C_Id=2000组:31528超出IQR范围,替换为组内众数313
  • C_Id=3000组:3000和4000超出IQR范围,替换为组内众数0

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

火山引擎 最新活动