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

Pandas按多列组合分组应用IQR法检测异常值报错修复

问题根源

原代码存在4处核心错误,直接触发报错或逻辑失效:

  • 用zip(itr1, itr2)遍历两列唯一值的写法错误:zip只会按位置一一配对元素,不会生成两个维度所有合法的分组组合,当两列唯一值数量不一致时,会直接丢失部分分组,后续计算时出现维度不匹配的广播错误。
  • 循环内重复计算全量分组的四分位值:循环中写的df.groupby(...)是对全表做分组统计,完全没有用到当前遍历的分组键(i,j)筛选对应分组数据,计算完全冗余。
  • 遍历groupby对象的取值逻辑错误:for x in df.groupby(...)[variable]拿到的x是(分组键名, 分组对应Series)的元组,不是单个数值,直接和阈值做比较会触发形状不匹配的报错。
  • 循环内提前return:第一次循环执行完就直接返回结果,根本不会遍历完所有分组。
修复方案

不需要写显式循环遍历分组,用pandas内置的transform方法可以直接把每个分组计算得到的阈值映射回原表每一行,代码更简洁、运行效率更高:

import pandas as pd

def tukeys_method(df, variable, group_col1, group_col2):
    # 按指定两个维度分组,计算每组目标列的统计值并映射回原表每一行
    grouped = df.groupby([group_col1, group_col2])[variable]
    q1 = grouped.transform('quantile', 0.25)
    q3 = grouped.transform('quantile', 0.75)
    iqr = q3 - q1

    # 计算各层级异常值围栏
    inner_low = q1 - 1.5 * iqr
    inner_high = q3 + 1.5 * iqr
    outer_low = q1 - 3 * iqr
    outer_high = q3 + 3 * iqr

    # 提取异常值对应的原表索引
    # 极异常值:超出3倍IQR围栏
    probable_outliers = df.index[(df[variable] <= outer_low) | (df[variable] >= outer_high)].tolist()
    # 潜在异常值:超出1.5倍IQR围栏
    possible_outliers = df.index[(df[variable] <= inner_low) | (df[variable] >= inner_high)].tolist()

    return probable_outliers, possible_outliers

# 函数调用
probable_outliers_tm, possible_outliers_tm = tukeys_method(df, "Price", "Region", "Product")
测试结果说明

注意你提供的样例数据构造代码中,Uganda对应的Product值写为XYZ,和上方表格中记录的ABC不一致,修正为一致后运行函数:

  • 无超出3倍IQR的极异常值,probable_outliers_tm返回空列表
  • 潜在异常值共2个,对应索引为:
    • South Africa 2018年Price=15的记录
    • Japan 2019年Price=0的记录
  • Uganda 2018年Price=1300的记录在对应分组的正常波动范围内,不会被识别为异常值。

内容的提问来源于stack exchange,提问作者A.N.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 11:06:16