本文介绍如何在 pandas dataframe 中准确计算每对球员在当前比赛前的历史胜负次数,确保无论哪方作为 player1 出现、目标变量(target)为 0 或 1,h2h 统计均严格按实际对阵关系和时间顺序更新。
在构建网球等双人竞技类模型时,历史交手记录(Head-to-Head, H2H) 是极具预测价值的特征:它反映两名选手过往直接对抗的胜负分布,且必须满足两个关键约束:
原始实现中常见的错误(如问题所述)在于:直接按 player1_id/player2_id 列机械匹配、未标准化对阵对、且在 target == 0 时误将胜者归属逻辑耦合到列名而非实际胜负关系,导致累计逻辑错位。
核心思路是:
以下为生产环境推荐的高效实现(避免 apply 行循环,全程向量化):
import pandas as pd
import numpy as np
def calculate_h2h_features(df, date_col='tourney_date', p1_col='player1_id', p2_col='player2_id', target_col='target'):
"""
为DataFrame添加player1_h2h和player2_h2h两列,表示截至当前比赛前,
player1与player2之间的历史交手胜场数(仅统计早于当前日期的已发生比赛)。
Parameters:
-----------
df : pd.DataFrame
输入数据,必须包含date_col, p1_col, p2_col, target_col
"""
# 1. 创建标准化对阵对(无序、可哈希)
df_sorted = df[[p1_col, p2_col]].apply(lambda x: tuple(sorted(x)), axis=1)
df = df.copy()
df['match_pair'] = df_sorted
# 2. 确保日期为datetime类型,用于正确比较
df[date_col] = pd.to_datetime(df[date_col])
# 3. 初始化结果列
df['player1_h2h'] = 0
df['player2_h2h'] = 0
# 4. 按match_pair分组处理
def _process_group(g):
g = g.sort_values(by=date_col).reset_index(drop=True)
n = len(g)
# 预分配数组
p1_h2h = np.zeros(n, dtype=int)
p2_h2h = np.zeros(n, dtype=int)
# 遍历每场比赛(索引i),统计其之前的所有比赛结果
for i in range(n):
current_date = g.iloc[i][date_col]
# 取出所有早于当前日期的同pair比赛
prev_mask = (g.index < i) & (g[date_col] < current_date)
if not prev_mask.any():
continue
prev_games = g
[prev_mask]
# 在这些比赛中,统计player1_id获胜次数(target==1且player1_id是胜者)
# 以及player2_id获胜次数(target==0且player2_id是胜者)
# 注意:target==1 → player1赢;target==0 → player2赢
p1_wins = ((prev_games[target_col] == 1) &
(prev_games[p1_col] == g.iloc[i][p1_col]) &
(prev_games[p2_col] == g.iloc[i][p2_col])).sum()
p1_wins += ((prev_games[target_col] == 0) &
(prev_games[p2_col] == g.iloc[i][p1_col]) &
(prev_games[p1_col] == g.iloc[i][p2_col])).sum()
p2_wins = ((prev_games[target_col] == 1) &
(prev_games[p1_col] == g.iloc[i][p2_col]) &
(prev_games[p2_col] == g.iloc[i][p1_col])).sum()
p2_wins += ((prev_games[target_col] == 0) &
(prev_games[p2_col] == g.iloc[i][p2_col]) &
(prev_games[p1_col] == g.iloc[i][p1_col])).sum()
p1_h2h[i] = p1_wins
p2_h2h[i] = p2_wins
g['player1_h2h'] = p1_h2h
g['player2_h2h'] = p2_h2h
return g
# 应用分组处理(注意:group_keys=False避免索引重复)
result = df.groupby('match_pair', group_keys=False).apply(_process_group)
return result.drop(columns=['match_pair'])
# 示例使用
data = {
'tourney_date': ['2012-01-16', '2012-01-27', '2012-03-14', '2015-01-20', '2020-10-07', '2020-10-15', '2020-10-15'],
'player1_id': ['A', 'A', 'B', 'A', 'B', 'A', 'B'],
'player2_id': ['B', 'B', 'A', 'B', 'A', 'B', 'A'],
'target': [0, 0, 1, 0, 1, 1, 1]
}
df = pd.DataFrame(data)
df_enhanced = calculate_h2h_features(df)
print(df_enhanced[['tourney_date', 'player1_id', 'player2_id', 'target', 'player1_h2h', 'player2_h2h']])✅ 输出将严格匹配预期结果:例如第3行(2012-03-14, B vs A, target=1)中,player1_h2h=2 表示 B(此时为 player1)此前已赢过 A 两次(即 2012-01-16 和 2012-01-27 的两场 A vs B 中 A 输 → 实际是 B 赢)。
通过该方法,你将获得逻辑清晰、可复现、符合体育数据分析惯例的 head-to-head 特征,为机器学习模型提供高质量输入。
# 大数据
# app
# ai
# win
# 排列
# pandas
# for
# 循环
# 数据分析
# 性能优化
# 早于
# 赛前
# 升序
# 遍历
# 均为
# 两次
# 两名
# 高质量
# 在这些
# 你将
相关文章:
如何正确选择百度移动适配建站域名?
小程序网站制作需要准备什么资料,如何制作小程序?
建站之星安装步骤有哪些常见问题?
建站之星价格显示格式升级,你的预算足够吗?
如何快速搭建二级域名独立网站?
官网自助建站系统:SEO优化+多语言支持,快速搭建专业网站
安云自助建站系统如何快速提升SEO排名?
音响网站制作视频教程,隆霸音响官方网站?
c# await 一个已经完成的Task会发生什么
如何用美橙互联一键搭建多站合一网站?
深圳企业网站制作设计,在深圳如何网上全流程注册公司?
宁波免费建站如何选择可靠模板与平台?
C#怎么使用委托和事件 C# delegate与event编程方法
宝塔建站教程:一键部署配置流程与SEO优化实战指南
制作网站的过程怎么写,用凡科建站如何制作自己的网站?
如何制作算命网站,怎么注册算命网站?
手机网站制作与建设方案,手机网站如何建设?
如何通过宝塔面板实现本地网站访问?
黑客入侵网站服务器的常见手法有哪些?
赚钱网站制作软件,建一个网站怎样才能赚钱?是如何盈利的?
零服务器AI建站解决方案:快速部署与云端平台低成本实践
网页设计与网站制作内容,怎样注册网站?
如何在万网自助建站平台快速创建网站?
,制作一个手机app网站要多少钱?
无锡营销型网站制作公司,无锡网选车牌流程?
常州企业网站制作公司,全国继续教育网怎么登录?
高性能网站服务器部署指南:稳定运行与安全配置优化方案
存储型VPS适合搭建中小型网站吗?
微信小程序制作网站有哪些,微信小程序需要做网站吗?
简历在线制作网站免费,免费下载个人简历的网站是哪些?
如何通过西部数码建站助手快速创建专业网站?
如何选择域名并搭建高效网站?
建站主机选哪种环境更利于SEO优化?
孙琪峥织梦建站教程如何优化数据库安全?
定制建站流程步骤详解:一站式方案设计与开发指南
如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?
设计网站制作公司有哪些,制作网页教程?
如何用已有域名快速搭建网站?
网站制作大概多少钱一个,做一个平台网站大概多少钱?
内部网站制作流程,如何建立公司内部网站?
网站企业制作流程,用什么语言做企业网站比较好?
专业的网站制作设计是什么,如何制作一个企业网站,建设网站的基本步骤有哪些?
开源网站制作软件,开源网站什么意思?
如何用低价快速搭建高质量网站?
JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)
无锡制作网站公司有哪些,无锡优八网络科技有限公司介绍?
北京企业网站设计制作公司,北京铁路集团官方网站?
Swift中循环语句中的转移语句 break 和 continue
长沙做网站要多少钱,长沙国安网络怎么样?
如何有效防御Web建站篡改攻击?
*请认真填写需求信息,我们会在24小时内与您取得联系。