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

如何按Name分组结合权重列表计算加权平均值?

解决方案

首先修正你代码中的错误(dpid应为Name),然后通过分组自定义函数实现按Name计算加权平均的需求。以下是两种实用实现方式:

方式1:生成各组加权平均汇总表

适合需要单独查看每个组加权结果的场景:

import pandas as pd
import numpy as np

data = [
    ['A',1,2,3,4],
    ['A',5,6,7,8],
    ['A',9,10,11,12],
    ['B',13,14,15,16],
    ['B',17,18,19,20],
    ['B',21,22,23,24],
    ['B',25,26,27,28],
    ['C',29,30,31,32],
    ['C',33,34,35,36],
    ['C',37,38,39,40],
]

df = pd.DataFrame(data, columns=['Name', 'num1', 'num2', 'num3', 'num4'])

def calculate_weighted_avg(group):
    n = len(group)
    # 按你的例子定义各组权重
    if n == 3:
        weights = [30, 30, 40]
    elif n == 4:
        weights = [10, 20, 30, 40]
    else:
        weights = [100/n]*n  # 其他长度组默认平均分配权重
    # 计算加权平均:(数值*权重)求和后除以权重总和
    weighted_avg = (group[['num1','num2','num3','num4']] * weights).sum() / sum(weights)
    return weighted_avg

# 按Name分组计算并生成汇总表
weighted_avg_df = df.groupby('Name').apply(calculate_weighted_avg).reset_index()
print(weighted_avg_df)

运行结果:

Name  num1  num2  num3  num4
0    A   6.0   7.0   8.0   9.0
1    B  21.0  22.0  23.0  24.0
2    C  34.0  35.0  36.0  37.0

验证你的例子:

  • 组A的num1:(1*30 +5*30 +9*40)/100 = 540/100 = 6.0,符合预期
  • 组B的num1:(13*10+17*20+21*30+25*40)/100 = 2100/100 =21.0,符合预期

方式2:将加权平均填充到原DataFrame每行

适合需要保留原数据结构,同时替换为组内加权平均的场景:

def fill_weighted_avg(group):
    n = len(group)
    if n ==3:
        weights = [30,30,40]
    elif n ==4:
        weights = [10,20,30,40]
    else:
        weights = [100/n]*n
    weighted_avg = (group[['num1','num2','num3','num4']] * weights).sum() / sum(weights)
    # 将加权平均广播到组内所有行
    group[['num1','num2','num3','num4']] = weighted_avg.values
    return group

# 应用到原DataFrame
df_weighted = df.groupby('Name').apply(fill_weighted_avg).reset_index(drop=True)
print(df_weighted)

运行结果:

Name  num1  num2  num3  num4
0    A   6.0   7.0   8.0   9.0
1    A   6.0   7.0   8.0   9.0
2    A   6.0   7.0   8.0   9.0
3    B  21.0  22.0  23.0  24.0
4    B  21.0  22.0  23.0  24.0
5    B  21.0  22.0  23.0  24.0
6    B  21.0  22.0  23.0  24.0
7    C  34.0  35.0  36.0  37.0
8    C  34.0  35.0  36.0  37.0
9    C  34.0  35.0  36.0  37.0

通用化调整(按组内行位置匹配权重列表)

如果你的weights = [10,20,30,40]是通用规则,组内第i行对应列表第i个权重(行数不足时取前n个),只需修改权重获取逻辑:

weights = [10,20,30,40]

def calculate_weighted_avg(group):
    n = len(group)
    group_weights = weights[:n]
    weighted_avg = (group[['num1','num2','num3','num4']] * group_weights).sum() / sum(group_weights)
    return weighted_avg

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 08:27:12