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

Pandas按主客队两列过滤DataFrame计算控球率平均值实现问题

问题需求

我有如下DataFrame:

Unnamed: 0  Datetime    HomeTeam    AwayTeam    Ball PossessionMatch_H  Ball PossessionMatch_A
0   0   2021-05-24 02:30:00 U. De Chile Everton                         68      32
1   1   2021-05-23 21:00:00 Huachipato  Colo Colo                       48      52
2   2   2021-05-23 18:30:00 Melipilla   Antofagasta                     47      53
3   3   2021-05-23 02:30:00 U. Espanola U. Catolica                     37      63
4   4   2021-05-23 00:00:00 S. Wanderers    O'Higgins                   29      71
... ... ... ... ... ... ...
57  57  2021-03-28 15:45:00 Palestino   Antofagasta                     58      42
58  58  2021-03-28 01:00:00 U. Espanola S. Wanderers                    50      50
59  59  2021-03-27 22:30:00 Colo Colo   Union La Calera                 58      42
60  60  2021-03-27 20:00:00 Everton O'Higgins                           54      46
61  61  2021-03-27 15:00:00 Curico Unido    Melipilla                   41      59

需要实现如下需求:

  • 按行计算主队、客队在本场比赛之前所有赛事的平均控球率
  • 新增Ball PossessionMatch_H/MP列存储本场主队的历史平均控球率
  • 新增Ball PossessionMatch_A/MP列存储本场客队的历史平均控球率
  • 结果直接追加到原DataFrame中,不要出现重复行
原代码问题排查
  • 分支判断逻辑错误:team in df['HomeTeam']是判断team是否在Series的索引中,而非判断是否在HomeTeam的值列表里,所以几乎所有球队都会进入else分支,导致仅生成Ball PossessionMatch_A/MP列
  • 数据重复:每次循环生成对应球队的所有匹配行,concat后每行会出现多次(和该行涉及的两支球队数量一致)
  • 结果收集逻辑缺失:if分支生成的current_df没有加入df_list3,导致if分支的计算结果完全丢失
  • 逻辑冗余:不需要拆分数据再合并,直接在原DataFrame上新增两列即可
修改后实现代码
import pandas as pd

# 第一步:先处理时间格式,按比赛时间升序排序,保证后续取历史数据逻辑正确
df['Datetime'] = pd.to_datetime(df['Datetime'])
df = df.sort_values('Datetime', ascending=True).reset_index(drop=True)

# 初始化两个新列
df['Ball PossessionMatch_H/MP'] = 0.0
df['Ball PossessionMatch_A/MP'] = 0.0

# 逐行计算历史平均控球率
for idx, row in df.iterrows():
    # 计算主队的历史平均控球率
    home_team = row['HomeTeam']
    # 取所有早于当前场次的该队比赛数据
    home_history = df[
        ((df['HomeTeam'] == home_team) | (df['AwayTeam'] == home_team)) 
        & (df.index < idx)
    ]
    if len(home_history) > 0:
        home_possession_sum = (
            home_history[home_history['HomeTeam'] == home_team]['Ball PossessionMatch_H'].sum()
            + home_history[home_history['AwayTeam'] == home_team]['Ball PossessionMatch_A'].sum()
        )
        df.loc[idx, 'Ball PossessionMatch_H/MP'] = round(home_possession_sum / len(home_history), 2)
    else:
        # 首次参赛没有历史数据,可根据需求赋值为NaN或者0
        df.loc[idx, 'Ball PossessionMatch_H/MP'] = pd.NA

    # 计算客队的历史平均控球率
    away_team = row['AwayTeam']
    away_history = df[
        ((df['HomeTeam'] == away_team) | (df['AwayTeam'] == away_team)) 
        & (df.index < idx)
    ]
    if len(away_history) > 0:
        away_possession_sum = (
            away_history[away_history['HomeTeam'] == away_team]['Ball PossessionMatch_H'].sum()
            + away_history[away_history['AwayTeam'] == away_team]['Ball PossessionMatch_A'].sum()
        )
        df.loc[idx, 'Ball PossessionMatch_A/MP'] = round(away_possession_sum / len(away_history), 2)
    else:
        df.loc[idx, 'Ball PossessionMatch_A/MP'] = pd.NA

# 如果需要恢复原始的降序排列,执行以下代码
df = df.sort_values('Datetime', ascending=False).reset_index(drop=True)
print(df)
输出效果示例
Unnamed: 0  Datetime    HomeTeam    AwayTeam    Ball PossessionMatch_H  Ball PossessionMatch_A  Ball PossessionMatch_H/MP   Ball PossessionMatch_A/MP
0   0   2021-05-24 02:30:00 U. De Chile Everton               68           32         50.33      43.5

内容的提问来源于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 22:15:07