如何用Python计算DataFrame中球队最近5场比赛的进球积分?
解决土耳其联赛球队过往5场主客场混合积分计算问题
核心问题分析
你当前代码仅按Home字段分组,只能统计球队作为主队的最近5场数据,完全忽略了他们作为客队的场次。要实现主客场混合的过往5场统计,需要先重构数据,把每个球队的所有主客场比赛统一整理,再计算滚动积分。
解决步骤
1. 重构数据:生成每个球队的单场记录
把每场比赛拆成两条独立记录——一条对应主队,一条对应客队,记录球队的进球、失球、主场状态,这样就能统一统计所有场次。
import pandas as pd # 读取并整理原始数据 webs = pd.read_csv('https://www.football-data.co.uk/mmz4281/2223/T1.csv') tk = webs[['Date','HomeTeam','AwayTeam','FTHG','FTAG','FTR']] tk.columns = ['Date','Home','Away','FT_Gols_H','FT_Gols_A','FT_Result'] # 转换日期格式(确保时间排序正确) tk['Date'] = pd.to_datetime(tk['Date'], dayfirst=True) # 生成主队记录:球队名、进球、失球、是否主场(1=主场,0=客场)、比赛日期 home_records = tk.rename(columns={ 'Home': 'Team', 'FT_Gols_H': 'Goals', 'FT_Gols_A': 'Conceded', }).assign(Is_Home=1)[['Team', 'Date', 'Goals', 'Conceded', 'Is_Home']] # 生成客队记录 away_records = tk.rename(columns={ 'Away': 'Team', 'FT_Gols_A': 'Goals', 'FT_Gols_H': 'Conceded', }).assign(Is_Home=0)[['Team', 'Date', 'Goals', 'Conceded', 'Is_Home']] # 合并所有球队记录并按球队+日期排序 team_records = pd.concat([home_records, away_records], ignore_index=True) team_records = team_records.sort_values(['Team', 'Date']).reset_index(drop=True)
2. 计算单场积分与滚动累计积分
按照规则计算单场的进球/失球积分,再用滚动窗口统计最近5场的累计值,shift(1)确保只取本场比赛之前的数据(符合赛前分析需求):
- 进球积分:主场进球每球1分,客场进球每球2分
- 失球积分:主场失球每球1分,客场失球每球2分
# 计算单场进球积分和失球积分 team_records['Goal_Per_Game'] = team_records.apply( lambda x: x['Goals'] * 1 if x['Is_Home'] else x['Goals'] * 2, axis=1 ) team_records['Concede_Per_Game'] = team_records.apply( lambda x: x['Conceded'] * 1 if x['Is_Home'] else x['Conceded'] * 2, axis=1 ) # 计算最近5场累计进球积分、失球积分 team_records['Last5_Goal_Points'] = team_records.groupby('Team')['Goal_Per_Game']\ .rolling(window=5, min_periods=1).sum().reset_index(0, drop=True).shift(1) team_records['Last5_Concede_Points'] = team_records.groupby('Team')['Concede_Per_Game']\ .rolling(window=5, min_periods=1).sum().reset_index(0, drop=True).shift(1)
3. 将积分合并回原比赛数据
把计算好的主客队过往积分匹配到原始比赛数据框中:
# 匹配主队的最近5场积分 tk = tk.merge( team_records[['Team', 'Date', 'Last5_Goal_Points', 'Last5_Concede_Points']], left_on=['Home', 'Date'], right_on=['Team', 'Date'], how='left' ).rename(columns={ 'Last5_Goal_Points': 'Home_Last5_Goal_Pts', 'Last5_Concede_Points': 'Home_Last5_Concede_Pts' }).drop('Team', axis=1) # 匹配客队的最近5场积分 tk = tk.merge( team_records[['Team', 'Date', 'Last5_Goal_Points', 'Last5_Concede_Points']], left_on=['Away', 'Date'], right_on=['Team', 'Date'], how='left' ).rename(columns={ 'Last5_Goal_Points': 'Away_Last5_Goal_Pts', 'Last5_Concede_Points': 'Away_Last5_Concede_Pts' }).drop('Team', axis=1)
最终效果
处理后的tk数据框会新增4个字段:
Home_Last5_Goal_Pts:主队赛前最近5场(主客场混合)的总进球积分Home_Last5_Concede_Pts:主队赛前最近5场的总失球积分Away_Last5_Goal_Pts:客队赛前最近5场的总进球积分Away_Last5_Concede_Pts:客队赛前最近5场的总失球积分
内容的提问来源于stack exchange,提问作者Pietro Mendonça
相关产品推荐
相关产品推荐

