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

Pandas按对局分组匹配最高分 为DataFrame新增winner列

问题:pandas按对局分组填充胜者列

我有一个存储桌游 Terraforming Mars 对局数据的DataFrame,计划使用pandas完成多项统计计算。该DataFrame包含不同计分规则对应的累计分数字段,以及Game(对局ID)、Player(玩家ID)、Coportation(所选企业)等属性字段,示例结构与数据如下:

列名信息:

>>> df.columns
Index(['Date', 'Game', 'Player', 'Coportation', 'TR', 'MILESTONES', 'AWARDS',
       'CARDS', 'GREENERY', 'CITIES+G', 'Total'],
      dtype='object')

字段类型信息:

>>> df.dtypes
Date           object
Game            int64
Player          int64
Coportation    object
TR              int64
MILESTONES      int64
AWARDS          int64
CARDS           int64
GREENERY        int64
CITIES+G        int64
Total           int64
dtype: object

头部样例数据:

>>> df.head()
          Date  Game  Player Coportation  ...  CARDS  GREENERY  CITIES+G  Total
0          NaN     3       1         NaN  ...     41         2         3     90
1          NaN     3       2         NaN  ...      6         8         9     78
2          NaN     3       3         NaN  ...     26         5        11     90
3          NaN     4       1         NaN  ...     44         6         2     97
4          NaN     4       2         NaN  ...     22         8         2     77

需要实现的常规统计需求包括:

  • 单局最高总分
  • 单局最低总分
  • 对局平均得分
  • 玩家个人历史最高分
  • 玩家个人历史最低分
  • 胜场最多玩家
  • 负场最多玩家
  • 表现最佳企业
  • 表现最差企业

当前需要先完成「胜场最多玩家」的前置步骤:为每个Game(对局)新增winner列,实现逻辑为:

  1. 遍历每一局游戏,获取该局Total列最高分对应的Player值
  2. 将该Player值填充到该局所有行的winner列中

逐行apply写if判断的方案无法覆盖分组取最大值对应字段的场景,需要可行实现方法。


回答

不需要写显式循环逐行处理,用pandas内置的分组变换逻辑1行代码就能实现,核心是用groupby + transform按对局分组直接广播最大值对应的玩家ID。

基础实现代码

# 按对局分组,找到每局Total最高的行对应的Player,广播填充到同组所有行
df['winner'] = df.groupby('Game')['Total'].transform(lambda x: df.loc[x.idxmax(), 'Player'])

逻辑说明

  1. groupby('Game')会把所有行按对局ID拆分为独立分组,每个分组对应同一局的所有玩家数据
  2. 对每个分组的Total列执行transform操作:x.idxmax()会返回当前分组里总分最高的行的索引,用该索引取对应行的Player值就是该局胜者
  3. transform会自动把计算出的胜者值对齐填充到该分组的每一行,不需要手动写循环匹配

平局场景适配

如果遇到样例中Game=3两个玩家同拿90分的平局场景,上面的代码默认取索引更靠前的玩家作为胜者。如果需要标记平局,可以调整逻辑:

def get_winner(group):
    max_total = group['Total'].max()
    winners = group[group['Total'] == max_total]['Player'].tolist()
    # 单胜者返回玩家ID,多胜者返回平局标记
    return winners[0] if len(winners) == 1 else 'tie'

df['winner'] = df.groupby('Game').apply(get_winner).loc[df['Game']].values

后续胜场统计参考

胜者列填充完成后,胜场统计直接按玩家去重计数即可,避免同一局多行重复计数:

win_counts = df.drop_duplicates(subset=['Game', 'winner'])['winner'].value_counts()
top_winner = win_counts.idxmax()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 17:15:43