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

Pandas使用Groupby分组计算行值占分组总和比例的实现问题

问题解决方案

原有代码错误原因

  1. 语法错误:df.groupby("ID").apply(row_sum: input=df["A"]) 不符合Python函数传参规范,且传入的df["A"]是完整数据集的A列,不是分组后的子集,逻辑完全不匹配。
  2. 变量命名冲突:自定义函数中用sum作为变量名,会覆盖Python内置的sum()函数,属于不规范的命名实践。
  3. 方法选择错误:直接对groupby对象使用apply默认返回的是分组聚合结果,无法直接映射到原数据集的每一行,更适合用transform方法做分组结果广播。

最简实现方式

无需自定义函数,用pandas内置的transform方法即可高效实现需求:

import pandas as pd

# 构造测试数据
df = pd.DataFrame({
    'ID': [1, 1, 1, 2, 2],
    'A': [2, 3, 4, 1, 2]
})

# 计算占比(默认输出浮点数)
df['B'] = df['A'] / df.groupby('ID')['A'].transform('sum')

# 如果需要输出"x/y"格式的分数字符串,可改用如下写法
df['B'] = df.apply(
    lambda x: f"{x['A']}/{df.groupby('ID')['A'].sum()[x['ID']]}",
    axis=1
)

运行后即可得到你预期的输出结果。


自定义apply的修正写法

如果你坚持要用自定义函数配合apply实现,可按如下方式调整代码:

def calc_group_ratio(group):
    # 传入的group是每个ID对应的子DataFrame
    group['B'] = group['A'] / group['A'].sum()
    return group

# group_keys=False避免额外生成分组索引
df = df.groupby('ID', group_keys=False).apply(calc_group_ratio)

类封装实现

以下是将逻辑封装为类和方法的示例,支持自定义参数:

import pandas as pd

class GroupRatioCalculator:
    def __init__(self, input_df):
        self.raw_df = input_df.copy()
        self.output_df = None

    def calculate(self, group_col: str, value_col: str, 
                  result_col: str = 'B', return_fraction_str: bool = False):
        """
        按指定列分组,计算数值列占分组总和的比例
        :param group_col: 分组维度的列名
        :param value_col: 要计算占比的数值列名
        :param result_col: 存储计算结果的列名,默认值为'B'
        :param return_fraction_str: 是否返回"x/y"格式的分数字符串,默认返回浮点型比例
        """
        df = self.raw_df.copy()
        group_sum = df.groupby(group_col)[value_col].sum()

        if return_fraction_str:
            sum_map = group_sum.to_dict()
            df[result_col] = df.apply(lambda x: f"{x[value_col]}/{sum_map[x[group_col]]}", axis=1)
        else:
            df[result_col] = df[value_col] / df.groupby(group_col)[value_col].transform('sum')
        
        self.output_df = df
        return self.output_df

调用示例:

# 初始化实例
calculator = GroupRatioCalculator(df)
# 调用方法获取结果
result = calculator.calculate(group_col='ID', value_col='A', return_fraction_str=True)

内容的提问来源于stack exchange,提问作者Kosta S.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 16:54:00