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

如何在pandas中计算列的分组加权聚合,实现赛事胜率到赛季评分转换

解决方案

问题原因分析

你之前的过滤操作失败是因为groupby + value_counts返回的结果中,outcome是多级索引的层级之一,并非数据列,所以直接按列过滤会报错。返回结果的索引默认是[season, opponent, outcome]三级,数值列存储的是占比。


分步实现方案(DF1→DF2→DF3)

步骤1:正确生成仅包含胜率的DF2

# 把outcome的w/l结果从索引转成列,直接提取胜场占比就是胜率
df2 = df1.groupby(["season", "opponent"])["outcome"].value_counts(normalize=True).unstack()
# 取w列作为胜率,没有胜场的对阵默认填充0,重命名列后重置索引
df2 = df2.get("w", 0).reset_index(name="win_rate")

步骤2:支持自定义权重的赛季评分计算(生成DF3)

支持传入自定义Lambda函数实现权重逻辑,完全匹配你给出的评分公式:

# weight_rule参数可传入自定义Lambda调整不同对手的权重
def calculate_season_score(group, weight_rule=lambda oppo: 2 if oppo == "A" else 1):
    group["weight"] = group["opponent"].apply(weight_rule)
    # 加权平均计算逻辑和示例公式完全对齐:权重总和 = A队2 + 其他队各1 = 队伍总数 + 1
    total_weighted_win = (group["win_rate"] * group["weight"]).sum()
    total_weight = group["weight"].sum()
    return total_weighted_win / total_weight

# 按赛季分组计算总评分,得到最终DF3
df3 = df2.groupby("season").apply(calculate_season_score).reset_index(name="season_score")

更高效的一步到位实现(无需生成中间DF2)

如果不需要用DF2做其他分析,可以直接从原始DF1计算得到DF3,减少内存占用:

def calc_score_from_raw(group, weight_rule=lambda oppo: 2 if oppo == "A" else 1):
    # 直接计算当前赛季每个对手的胜率
    oppo_win_rate = group.groupby("opponent")["outcome"].apply(lambda x: (x == "w").mean())
    # 应用权重规则计算加权分
    weights = oppo_win_rate.index.to_series().apply(weight_rule)
    return (oppo_win_rate * weights).sum() / weights.sum()

df3 = df1.groupby("season").apply(calc_score_from_raw).reset_index(name="season_score")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 20:45:03