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

如何在Pandas分组DataFrame中添加异常值占比列?

解决分组计算成本异常值占比的问题

嘿,我来帮你搞定这个异常值占比的计算问题!首先咱们先理清楚你遇到的核心问题,然后一步步修正代码,让它正常工作。

先拆解问题

你原来的思路是对的:按code分组后,聚合出sum和mean,再新增异常值占比列。但问题出在自定义函数的调用方式,以及一些不必要的冗余代码上。

第一步:修正自定义异常值函数

首先,咱们把is_outlier函数调整得更清晰,确保它能正确接收每个组的cost序列,返回一个标量(异常值占比)。这里要注意:

  • 要导入scipy.stats的iqr和numpy
  • 明确异常值的判断逻辑(上下界都算,还是只算上界,根据你的需求调整)
  • 处理观测数不足的情况(返回NaN)

修正后的函数:

import pandas as pd
import numpy as np
from scipy.stats import iqr

def is_outlier(s):
    # 生产环境中改成 >=100,示例中暂时放宽条件
    if len(s) >= 1:
        q1 = s.quantile(0.25)
        q3 = s.quantile(0.75)
        iqr_val = iqr(s)
        # 计算异常值上下界(你可以只保留上界或下界,根据需求调整)
        lower_bound = q1 - 1.5 * iqr_val
        upper_bound = q3 + 1.5 * iqr_val
        # 标记异常值并计算占比
        outlier_mask = (s < lower_bound) | (s > upper_bound)
        return outlier_mask.mean()
    else:
        return np.nan

第二步:正确分组聚合(一步到位)

你原来的groupby代码里.apply(pd.Series)是多余的,因为agg(['sum', 'mean'])已经直接返回DataFrame了。咱们可以直接在agg里把自定义函数加进去,一步得到所有需要的列:

# 示例数据
data = {'code': ['a', 'b', 'a', 'c', 'c', 'c', 'c'], 'cost': [10, 20, 100, 10, 10, 500, 10]}
df = pd.DataFrame(data)

# 一步完成分组聚合
grouped = df.groupby('code')['cost'].agg(
    sum='sum',
    mean='mean',
    is_outlier=is_outlier
).reset_index()

print(grouped)

运行后,如果你把函数里的判断条件改成len(s)>=1,就能得到符合你预期格式的结果(根据异常值定义不同,数值会对应变化)。

备选方案:给已有分组结果加列

如果你已经有了包含sum和mean的grouped DataFrame,也可以单独计算异常值占比再合并进去:

# 先计算sum和mean
grouped = df.groupby('code')['cost'].agg(['sum', 'mean']).reset_index()
# 计算每个组的异常值占比
outlier_ratios = df.groupby('code')['cost'].apply(is_outlier)
# 合并到grouped中
grouped['is_outlier'] = grouped['code'].map(outlier_ratios)

为什么原来的写法不行?

  1. 你原来的.apply(pd.Series)是冗余操作,agg(['sum','mean'])已经返回结构化的DataFrame了。
  2. 如果直接把is_outlier放进agg的列表里(比如agg(['sum','mean', is_outlier])),虽然也能工作,但用字典形式指定列名会更清晰,避免自动生成奇怪的列名。
  3. 确保函数返回的是标量(比如mean()的结果是单个数值),而不是Series,这样agg才能正确处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:52:41