Pandas如何为列值集合匹配的DataFrame行标注同组唯一ID
Pandas 为同场赛事双记录分配统一唯一ID
问题描述
现有存储赛事结果的Pandas DataFrame,包含如下字段:
Date:比赛日期,已转换为datetime类型Team:当前记录所属球队Home:当前记录所属球队是否为主场Opp:对阵对手球队Rslt:当前记录所属球队的比赛胜负结果
同一场比赛会对应两条记录,分别归属参赛的两支球队(例如2017-04-02 NYY对阵TBR的比赛,会同时存在NYY战败、TBR获胜两条记录)。需要将同一场比赛的行对归为同一组,为每组分配唯一数字ID,用于后续分组操作或设置MultiIndex。
前期已尝试拼接日期、球队、对手字段生成Match列,通过集合差集运算判断两行的参赛队、日期是否一致,单条验证逻辑可正常运行,但无法批量为所有匹配行对分配统一ID;尝试过.isin()、pd.DataFrame.lookup等方法均未得到理想结果,需要更高效简洁的实现方案。
测试样例数据
import pandas as pd df = pd.DataFrame({ 'Date': ['2017-04-02', '2017-04-02', '2017-04-02', '2017-04-02', '2017-04-02', '2017-04-02'], 'Team': ['CHC', 'ARI', 'NYY', 'TBR', 'STL', 'SFG'], 'Home': [True, False, True, False, False, True], 'Opp': ['STL', 'SFG', 'TBR', 'NYY', 'CHC', 'ARI'], 'Rslt': ['L', 'W', 'L', 'W', 'W', 'L'] }) df['Date'] = pd.to_datetime(df['Date'])
样例数据运行输出:
Date Team Home Opp Rslt 0 2017-04-02 CHC True STL L 1 2017-04-02 ARI False SFG W 2 2017-04-02 NYY True TBR L 3 2017-04-02 TBR False NYY W 4 2017-04-02 STL False CHC W 5 2017-04-02 SFG True ARI L
前期验证集合匹配逻辑的代码输出符合预期:同一场比赛的两条记录集合差集为空返回False,不同比赛记录集合差集非空返回True,但无法落地批量处理。
实现方案
核心逻辑不需要做逐行集合匹配,只需要生成不区分球队顺序的同场比赛唯一标识:对每条记录的参赛两队按固定规则(比如字母序)排序后和日期拼接,同一场比赛的两条记录生成的标识完全一致,再将标识转换为分类编码即可得到连续的唯一数字ID。
实现代码
# 生成不区分主客/记录顺序的比赛唯一键 df['match_key'] = df.apply( lambda row: f"{row['Date'].strftime('%Y-%m-%d')}_{'_'.join(sorted([row['Team'], row['Opp']]))}", axis=1 ) # 将唯一键转换为连续数字ID df['MatchID'] = df['match_key'].astype('category').cat.codes
运行结果
Date Team Home Opp Rslt match_key MatchID 0 2017-04-02 CHC True STL L 2017-04-02_CHC_STL 0 1 2017-04-02 ARI False SFG W 2017-04-02_ARI_SFG 1 2 2017-04-02 NYY True TBR L 2017-04-02_NYY_TBR 2 3 2017-04-02 TBR False NYY W 2017-04-02_NYY_TBR 2 4 2017-04-02 STL False CHC W 2017-04-02_CHC_STL 0 5 2017-04-02 SFG True ARI L 2017-04-02_ARI_SFG 1
方案优势
- 效率高:避免逐行匹配、集合运算的开销,基于Pandas内置分类编码实现,十万级以上数据量也可快速处理
- 准确率高:只要比赛日期相同、参赛两队一致,无论
Team和Opp字段顺序如何,排序后生成的唯一键完全相同,不会出现错配 - 兼容性好:生成的
MatchID是从0开始的连续整数,可直接用于groupby分组、设置MultiIndex等后续操作
如果不需要保留中间生成的match_key列,可直接执行df.drop(columns='match_key', inplace=True)删除。
内容的提问来源于stack exchange,提问作者MRT
相关产品推荐
相关产品推荐

