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

如何基于Pandas列条件构建网球选手对手映射字典?

网球选手对手字典生成方案

问题描述

给出的网球数据集如下:

tourney_id = ['French Open 2018','French Open 2018','Wimbledon 2018','Wimbledon 2018','Australian Open 2019','Australian Open 2019','US Open 2019','US Open 2019']
player_name = ['Novak Djokovic','Roger Federer','Andy Murray','Rafael Nadal','John Isner','Novak Djokovic','Andy Murray','Roger Federer']
match_num = [103, 103, 217, 217, 104, 104, 243, 243]

df = pd.DataFrame(list(zip(tourney_id, player_name, match_num)),
            columns =['TournamentID','Name','MatchID'])

需要生成一个字典,键为选手姓名,值是该选手的所有对手列表(对手定义为同一TournamentID和MatchID下的其他选手),目标格式如下:

{'Novak Djokovic': ['Roger Federer','John Isner'],
 'Roger Federer': ['Novak Djokovic','Andy Murray'],
 'Andy Murray': ['Rafael Nadal','Roger Federer'],
 'Rafael Nadal': ['Andy Murray'],
 'John Isner': ['Novak Djokovic']}

尝试过df.set_index(['TournamentID','MatchID'])['Name'].to_dict(),但未得到预期结果,需实现正确的生成逻辑。

解决方案

可以通过分组遍历的方式实现,核心逻辑是把同一赛事同一场比赛的选手归为一组,组内选手互为对手,再逐个整理到字典中。

实现代码

import pandas as pd

# 初始化数据集
tourney_id = ['French Open 2018','French Open 2018','Wimbledon 2018','Wimbledon 2018','Australian Open 2019','Australian Open 2019','US Open 2019','US Open 2019']
player_name = ['Novak Djokovic','Roger Federer','Andy Murray','Rafael Nadal','John Isner','Novak Djokovic','Andy Murray','Roger Federer']
match_num = [103, 103, 217, 217, 104, 104, 243, 243]

df = pd.DataFrame(list(zip(tourney_id, player_name, match_num)),
            columns =['TournamentID','Name','MatchID'])

# 初始化空字典存储结果
opponent_dict = {}

# 按赛事+比赛ID分组,遍历每个分组
for _, group in df.groupby(['TournamentID', 'MatchID']):
    current_players = group['Name'].tolist()
    # 给组内每个选手添加对手
    for player in current_players:
        # 筛选出组内除自己外的其他选手作为对手
        opponents = [p for p in current_players if p != player]
        # 字典中无该选手则初始化列表,再添加对手
        if player not in opponent_dict:
            opponent_dict[player] = []
        opponent_dict[player].extend(opponents)

print(opponent_dict)

代码说明

  1. groupby(['TournamentID', 'MatchID']):将同一赛事、同一场比赛的选手归为一组,确保每组内的选手都是直接对手关系。
  2. 遍历每个分组,取出该组的选手列表,对每个选手筛选出除自身外的其他成员作为对手。
  3. 用字典存储每个选手的对手列表,若选手首次出现则初始化空列表,再将对手添加进去。

简洁版实现

也可以用apply和字典推导简化代码:

# 分组后获取每组的选手列表
match_groups = df.groupby(['TournamentID', 'MatchID'])['Name'].apply(list).tolist()

# 构建对手字典
opponent_dict = {}
for players in match_groups:
    for player in players:
        # setdefault自动初始化空列表,避免判断
        opponent_dict.setdefault(player, []).extend([p for p in players if p != player])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 05:33:29