python - 是否有一种更简洁的方法来编写代码以在数据框中使用组均值有条件地替换异常值
问题描述
对于下面的 DF - 在值列中,产品 3(即 100)和产品 4(即 98)具有异常值。我想要
按 ['Class'] 分组
获得不包括异常值的 [Value] 的平均值
用步骤 2 中计算的平均值替换异常值。
任何关于如何构造代码的建议都非常感谢。我的代码在给定示例表的情况下可以工作,但我有一种感觉,当我在真正的解决方案中实施时,它可能无法工作。
Product,Class,Value
0 1 A 5
1 2 A 4
2 3 A 100
3 4 B 98
4 5 B 20
5 6 B 25
我的代码实现:
# Establish the condition to remove the outlier rows from the DF
stds = 1.0
filtered_df = df[~df.groupby('Class')['Value'].transform(lambda x: abs((x-x.mean()) / x.std()) > stds)]
输出:
Product Class Value
0 1 A 5
1 2 A 4
4 5 B 20
5 6 B 25
# compute mean of each class without the outliers
class_means = filtered_df[['Class', 'Value']].groupby(['Class'])['Value'].mean()
输出:
Class
A 4.5
B 22.5
#extract rows in DF that are outliers and fail the test
outlier_df = df[df.groupby('Class')['Value'].transform(lambda x: abs((x-x.mean()) / x.std()) > stds)]
outlier_df
输出:
Product Class Value
2 3 A 100
3 4 B 98
#replace outlier values with computed means grouped by class
outlier_df['Value'] = np.where((outlier_df.Class == class_means.index), class_means,outlier_df.Value)
outlier_df
输出:
Product Class Value
2 3 A 4.5
3 4 B 22.5
#recombine cleaned dataframes
df_cleaned = pd.concat([filtered_df,outlier_df], axis=0 )
df_cleaned
输出:
Product Class Value
0 1 A 5.0
1 2 A 4.0
4 5 B 20.0
5 6 B 25.0
2 3 A 4.5
3 4 B 22.5
解决方案
进行如下操作:
从您的代码开始:
stds = 1.0
将您的 lambda 函数保存在一个变量下:
isOutlier = lambda x: abs((x - x.mean()) / x.std()) > stds
定义以下函数,以应用于每个组:
def newValue(grp): val = grp.Value outl = isOutlier(val) return val.mask(outl, val[~outl].mean())
生成新的值列:
df.Value = df.groupby('Class', group_keys=False).apply(newValue)
结果是:
Product Class Value
0 1 A 5.0
1 2 A 4.0
2 3 A 4.5
3 4 B 22.5
4 5 B 20.0
5 6 B 25.0
您甚至不会丢失原始的行顺序。
编辑
或者您可以将 lambda 函数的内容“合并”到newValue中 (因为您不会在任何其他地方调用它):
def newValue(grp):
val = grp.Value
outl = abs((val - val.mean()) / val.std()) > stds
return val.mask(outl, val[~outl].mean())
推荐阅读
- flutter - 如何将一个项目(或 Text())放在另一个项目(或 Text())的右上方 Column()下方?
- java - 使用私有方法的 Spring Boot 事务传播
- c# - EFCore 无法将值 NULL 插入列
- azure - Azure AD B2C 和个人帐户 Blazor Wasm ASP .NET Core 5
- arm - 使用 openocd 和 contiker ng 的 gdb 中的行号不正确
- kotlin - 无法使用事件侦听器通过 JAVA Admin SDK 从 Firebase 实时数据库中检索数据
- fluttermap - 我需要检查标记是否在地图上的多边形内颤动
- php - CodeIgniter 在从控制器调用的构造中获取当前库函数名称的名称
- python-2.7 - 加载数据文件以检查有关数据的基本详细信息,任何人都可以纠正代码以正常运行吗?
- javascript - 在粘贴之前删除某些文本