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

如何对筛选后的pandas DataFrame按行计算球队历史场均进球并新增列

足球赛事历史场均进球计算实现方案

前置要求

先确保你的数据集按比赛时间Datetime升序排序,否则“当前行之前的历史比赛”逻辑无法成立:

import pandas as pd
# 按比赛时间升序重排数据
df = df.sort_values('Datetime').reset_index(drop=True)

场景1:计算球队主场场均进球(仅统计当前行前的历史主场场次)

用分组累计平均+偏移排除当前场次即可实现:

df['AverageG_Team_plays_home'] = df.groupby('HomeTeam')['HomeGol']\
                                   .apply(lambda x: x.expanding().mean().shift(1))

说明:expanding()实现累计计算,shift(1)把计算结果向下偏移一行,排除当前场次的进球数据,球队首次主场比赛对应值为NaN,符合预期。如果需要把首次比赛的默认值改为0,可在语句末尾加.fillna(0)。

场景2:计算球队客场场均进球(仅统计当前行前的历史客场场次)

逻辑和主场计算一致,按客队分组、取客场进球计算即可:

df['AverageG_Team_plays_at_away'] = df.groupby('AwayTeam')['AwayGol']\
                                      .apply(lambda x: x.expanding().mean().shift(1))

场景3:计算球队全参赛场均进球(统计当前行前的所有主客场场次)

需要先把宽表转成长表统计所有参赛记录,再把结果拼回原表:

# 1. 把每场比赛拆为主队、客队两条参赛记录,生成长表
match_long = pd.melt(df.reset_index(), 
                     id_vars=['index', 'Datetime'], 
                     value_vars=['HomeTeam', 'AwayTeam'],
                     var_name='TeamType', 
                     value_name='Team')
# 2. 匹配每条参赛记录对应的进球数
match_long['Goal'] = match_long.apply(
    lambda x: df.loc[x['index'], 'HomeGol'] if x['TeamType'] == 'HomeTeam' else df.loc[x['index'], 'AwayGol'],
    axis=1
)
# 3. 按球队分组计算截至前一场的全场景场均进球
match_long['avg_all'] = match_long.groupby('Team')['Goal']\
                                  .apply(lambda x: x.expanding().mean().shift(1))
# 4. 把计算结果拆分回主客场列,拼回原DataFrame
home_avg_all = match_long[match_long['TeamType'] == 'HomeTeam'].set_index('index')['avg_all']
away_avg_all = match_long[match_long['TeamType'] == 'AwayTeam'].set_index('index')['avg_all']
df['AverageG_Team_plays_at_both_home'] = home_avg_all
df['AverageG_Team_plays_at_both_away'] = away_avg_all

以上代码直接运行后,所有计算结果会自动作为新列追加到原DataFrame中,覆盖你提出的三个问题点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 21:36:08