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

基于99分位数分组去除Pandas数据异常值的问题求助

按分组基于99分位数移除异常值的正确实现

让我来帮你搞定这个问题!你尝试的代码之所以没得到预期结果,核心问题在于额外加入了x > x.quantile(0.01)的条件——在小样本数据中,0.01分位数通常等于组内最小值,这会把等于最小值的行(比如B组的3.3)错误过滤掉,不符合你的需求。

下面是几种符合你预期的正确实现方式:

方法一:仅过滤99分位数以上的异常值(完美匹配你的示例)

直接移除大于等于99分位数的数值(你的示例中要移除的正好是每组的99分位数对应值),代码如下:

import pandas as pd
df = pd.DataFrame({'Group': ['A','A','A','B','B','B','B'], 'count': [1.1,11.2,1.1,3.3,3.40,3.3,100.0]})

# 按分组过滤掉大于99分位数的值
result_df = df[df.groupby("Group")['count'].transform(lambda x: x < x.quantile(0.99))]
print(result_df)

运行后会输出你期望的结果:

Group  count
0     A    1.1
2     A    1.1
3     B    3.3
4     B    3.4
5     B    3.3

为什么这个代码有效?

  • groupby("Group")['count'].transform(...)会为每一行计算其所在组的99分位数,返回与原数据长度一致的布尔数组;
  • 我们只保留count值小于组内99分位数的行,正好移除了你示例中的A组11.2和B组100.0。

方法二:高效的非lambda实现(适合大数据集)

如果你处理的是大数据集,使用merge的方式性能更优,避免lambda的开销:

# 计算每组的99分位数并命名列
quant_99 = df.groupby('Group')['count'].quantile(0.99).rename('quant_99')
# 合并分位数到原数据
df_with_quant = df.merge(quant_99, on='Group')
# 过滤并清理多余列
result_df = df_with_quant[df_with_quant['count'] < df_with_quant['quant_99']].drop('quant_99', axis=1)

扩展:双向过滤1%以下和99%以上的异常值

如果你确实需要同时过滤两端的异常值,但不想过滤等于分位数的行,只需调整条件为>=和<=:

result_df = df[df.groupby("Group")['count'].transform(lambda x: (x >= x.quantile(0.01)) & (x <= x.quantile(0.99)))]

注意:在你的示例中,这个代码会保留A组的11.2(因为它等于99分位数),所以不符合你的预期;如果需要双向过滤且移除等于分位数的值,就用>和<。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:16:31