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

如何基于多列值用查找函数在Pandas DataFrame中新增列

解决方法:匹配对手的累计平均值列

我是Python新手,用Google Colab处理20支英超球队单赛季比赛的CSV数据。先计算各队的累计平均值,再合并成一个大DataFrame。当前DataFrame包含Date、Team、Opposition、cum_avg_xG等列(cum_avg_xG是球队截至对应日期的预期进球平均xG值),但存在比赛重复记录(比如曼城vs伯恩茅斯和伯恩茅斯vs曼城是同一场比赛)。现在需要新增opposition_cum_avg_xG列,根据Date和Opposition匹配对手的cum_avg_xG值(比如曼城对阵伯恩茅斯的行中,该列取伯恩茅斯的0.85),后续还要对cum_avg_GF等其他累计列做相同操作,不知道怎么基于多列在同一个DataFrame里实现这类查找。


核心逻辑

要实现这个需求,本质是把原数据里的球队累计值转换成一个可查询的"对手数据字典",然后通过日期+对手球队的组合,把对应的值匹配回去。

具体步骤

  1. 提取对手映射表:从合并后的大DataFrame里,把Date、Team和所有累计列单独拎出来,把Team改名为Opposition——这样这张表就代表了"某日期下,某球队的累计值",正好对应原数据里"某日期下,对阵该球队的对手累计值"。
  2. 清理重复记录:因为同一场比赛会被两支球队各记录一次,所以映射表里可能存在重复的(Date, Opposition)组合,需要先去重,确保每个组合只有一条有效数据。
  3. 合并匹配数据:用pd.merge把映射表和原数据关联起来,匹配键就是Date和Opposition,自动把对手的累计值填充到新列里。

修改后的完整代码

# 上传文件到Colab环境
from google.colab import files
upload = files.upload()

# 导入所需库
import pandas as pd
import numpy as np
import glob
import os

# 定义计算累计平均值的函数
def myfunction(team):
    df_team = pd.read_csv(team)
    # 计算各指标的累计平均值
    df_team['cum_avg_xG'] = df_team['xG'].expanding().mean()
    df_team['cum_avg_GF'] = df_team['GF'].expanding().mean()
    df_team['cum_avg_GA'] = df_team['GA'].expanding().mean()
    df_team['cum_avg_shots'] = df_team['Sh'].expanding().mean()
    # 累计值下移一行(确保是该场比赛前的累计数据)
    df_team[['cum_avg_xG', 'cum_avg_GF', 'cum_avg_GA', 'cum_avg_shots']] = df_team[
        ['cum_avg_xG','cum_avg_GF', 'cum_avg_GA', 'cum_avg_shots']
    ].shift(1)
    df_team = df_team.reset_index(drop=True)
    return df_team

# 合并所有球队的CSV数据
path = '/content/' 
all_files = glob.glob(os.path.join(path , "*.csv"))

team_temp = []
for filename in all_files:
    df = myfunction(filename)
    team_temp.append(df)
df_allteam = pd.concat(team_temp, axis=0, ignore_index=True)

# ------------------------------
# 新增:匹配对手的累计平均值列
# ------------------------------
# 1. 创建对手数据映射表,重命名Team为Opposition
cum_columns = ['cum_avg_xG', 'cum_avg_GF', 'cum_avg_GA', 'cum_avg_shots']
opponent_map = df_allteam[['Date', 'Team'] + cum_columns].rename(
    columns={'Team': 'Opposition'}
)
# 清理重复记录:确保每个(Date, Opposition)组合只有一条数据(保留最后一条)
opponent_map = opponent_map.drop_duplicates(subset=['Date', 'Opposition'], keep='last')

# 2. 将对手数据合并到原DataFrame
df_allteam = pd.merge(
    df_allteam,
    opponent_map,
    on=['Date', 'Opposition'],
    how='left',
    suffixes=('', '_opponent')
)

# 3. 重命名对手列,统一前缀为opposition_
for col in cum_columns:
    df_allteam.rename(columns={f'{col}_opponent': f'opposition_{col}'}, inplace=True)

# 查看处理后的结果
df_allteam.head()

关键细节说明

  • 去重操作:drop_duplicates(subset=['Date', 'Opposition'], keep='last')是为了避免合并后出现重复行,如果你的原始数据里每个(Date, Team)都是唯一的,这一步可以跳过,但加上更稳妥。
  • 左连接方式:how='left'保证原DataFrame的所有行都保留,要是遇到赛季第一场比赛(对手还没有累计数据),对应列会显示NaN,可以根据需求用df_allteam.fillna(0, inplace=True)填充。
  • 列名重命名:通过后缀区分原列和对手列,再统一改成opposition_cum_avg_xG这种格式,方便后续识别和使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 08:29:56