Python实现足球赛事数据中球队主客场进球的3场滚动求和
计算球队最近3场比赛(主客场)的滚动进球总和
你遇到的问题很典型——原代码只统计了主场的进球滚动和,没把客场的比赛算进去。要解决这个问题,核心是先把数据转换成每一行对应一支球队的一场比赛的格式,这样才能让rolling正确覆盖主客场所有赛事。
下面是具体的实现步骤和代码:
步骤1:重构数据格式
首先,我们需要把原DataFrame拆成两部分:主场球队的进球记录,和客场球队的进球记录,然后合并成一个包含所有球队所有比赛的数据集。假设你的原DataFrame名为df,包含Date(比赛日期,用来排序)、HomeTeam、AwayTeam、FTHG、FTAG这些列:
import pandas as pd # 拆分主场和客场数据,统一列名 home_records = df[["Date", "HomeTeam", "FTHG"]].rename(columns={"HomeTeam": "Team", "FTHG": "Goals"}) away_records = df[["Date", "AwayTeam", "FTAG"]].rename(columns={"AwayTeam": "Team", "FTAG": "Goals"}) # 合并成所有球队的完整比赛记录 all_team_games = pd.concat([home_records, away_records], ignore_index=True)
步骤2:按时间排序并计算滚动总和
滚动计算的前提是数据按球队+比赛时间排序,这样才会计算「时间上最近的3场」,而不是乱序的3场:
# 按球队和比赛日期排序(如果你的时间列不是Date,换成对应的列名比如Round) all_team_games = all_team_games.sort_values(by=["Team", "Date"]) # 计算最近3场的滚动进球总和 # min_periods=1表示球队比赛不足3场时,计算现有场次的总和(比如前2场就加前2场的进球) # 如果想让不足3场时显示NaN,去掉min_periods=1即可 all_team_games["Rolling_3_Goals"] = all_team_games.groupby("Team")["Goals"].rolling(3, min_periods=1).sum().reset_index(drop=True)
步骤3:(可选)将结果合并回原DataFrame
如果需要把滚动进球数添加到原比赛数据中(比如给每场比赛的主客队都加上他们的最近3场进球总和),可以用merge操作:
# 给原数据添加主场球队的滚动进球数 df = df.merge( all_team_games[["Date", "Team", "Rolling_3_Goals"]], left_on=["Date", "HomeTeam"], right_on=["Date", "Team"], how="left" ).rename(columns={"Rolling_3_Goals": "Home_Rolling_3_Goals"}).drop("Team", axis=1) # 给原数据添加客场球队的滚动进球数 df = df.merge( all_team_games[["Date", "Team", "Rolling_3_Goals"]], left_on=["Date", "AwayTeam"], right_on=["Date", "Team"], how="left" ).rename(columns={"Rolling_3_Goals": "Away_Rolling_3_Goals"}).drop("Team", axis=1)
关键注意点
- 必须排序:如果没有按时间排序,
rolling会按数据的原始顺序计算,得到的结果不是「最近3场」,而是乱序的3场,这会完全出错。 - 时间列的必要性:如果你的数据没有
Date列,一定要有其他能表示比赛先后顺序的列(比如联赛轮次Round),否则无法正确排序。 - min_periods参数:根据需求调整,默认是3,这时候球队前2场比赛的滚动和会是
NaN;设置min_periods=1则会计算现有场次的总和。
内容的提问来源于stack exchange,提问作者Martin Yordanov Georgiev
相关产品推荐
相关产品推荐

