Pandas实战:如何依据当前行之前的所有行修改当前行条目
用Pandas原生方案计算球队累计胜场数
我正在借助英格兰足球比分数据学习Pandas,现有一份按日期排序的比赛数据,其中FTR字段代表全场比赛结果:H为主队获胜,A为客队获胜,D为平局。我尝试创建HTWTD(主队到当前为止的累计胜场数)和ATWTD(客队到当前为止的累计胜场数)两列,但目前的方法仅在球队首次参赛时数据正确——比如第9行中Leeds作为主队获胜,他们在第2行已以客队身份赢过一场,此时HTWTD应显示为2,但当前仅为1。
我需要的逻辑是:对每一行,查找当前行之前的所有记录,获取目标球队之前的累计胜场数,加上当前这场的胜场(若获胜)填入对应列;若之前未参赛,则按当前胜场数(1或0)填写。希望用Pandas原生方法实现,无需编写自定义Python函数。
附原始数据表格:
| Row | Date | HomeTeam | AwayTeam | FTR | HTWTD | ATWTD |
|---|---|---|---|---|---|---|
| 0 | 12/09/2020 | Fulham | Arsenal | A | 0 | 1 |
| 1 | 12/09/2020 | Crystal Palace | Southampton | H | 1 | 0 |
| 2 | 12/09/2020 | Liverpool | Leeds | H | 0 | 1 |
| 3 | 12/09/2020 | West Ham | Newcastle | A | 0 | 1 |
| 4 | 13/09/2020 | West Brom | Leicester | A | 0 | 1 |
| 5 | 13/09/2020 | Tottenham | Everton | A | 0 | 1 |
| 6 | 14/09/2020 | Brighton | Chelsea | A | 0 | 1 |
| 7 | 14/09/2020 | Sheffield United | Wolves | A | 0 | 1 |
| 8 | 19/09/2020 | Everton | West Brom | H | 1 | 0 |
| 9 | 19/09/2020 | Leeds | Fulham | H | 1 | 0 |
解决方案(Pandas原生实现)
核心思路是先统一整理所有球队的胜场记录,再按比赛顺序计算累计胜场,最后映射回原数据:
1. 拆分并合并球队胜场记录
先分别标记主、客队的胜场,再将主、客队视角的记录合并为统一结构:
import pandas as pd # 生成主、客队胜场标记(1表示获胜,0表示未获胜) df['home_win'] = (df['FTR'] == 'H').astype(int) df['away_win'] = (df['FTR'] == 'A').astype(int) # 拆分主队记录:球队名、胜场、日期 home_records = df[['Date', 'HomeTeam', 'home_win']].rename(columns={'HomeTeam': 'Team', 'home_win': 'Win'}) # 拆分客队记录:球队名、胜场、日期 away_records = df[['Date', 'AwayTeam', 'away_win']].rename(columns={'AwayTeam': 'Team', 'away_win': 'Win'}) # 合并所有记录并按日期排序(原数据已排序,此步骤确保顺序正确) all_records = pd.concat([home_records, away_records]).sort_values('Date').reset_index(drop=True)
2. 计算每支球队的累计胜场
用groupby结合cumsum实现按球队的累计胜场计算:
# 按球队分组,计算到当前记录为止的累计胜场 all_records['Cumulative_Wins'] = all_records.groupby('Team')['Win'].cumsum()
3. 将累计胜场映射回原数据
通过合并操作,把累计胜场分别匹配到原数据的HTWTD和ATWTD列:
# 为主队匹配累计胜场 df = pd.merge( df, all_records.groupby(['Team', 'Date'])['Cumulative_Wins'].last().reset_index(), left_on=['HomeTeam', 'Date'], right_on=['Team', 'Date'], how='left' ).rename(columns={'Cumulative_Wins': 'HTWTD'}).drop('Team', axis=1) # 为客队匹配累计胜场 df = pd.merge( df, all_records.groupby(['Team', 'Date'])['Cumulative_Wins'].last().reset_index(), left_on=['AwayTeam', 'Date'], right_on=['Team', 'Date'], how='left' ).rename(columns={'Cumulative_Wins': 'ATWTD'}).drop('Team', axis=1) # 保留原始列顺序 df = df[['Row', 'Date', 'HomeTeam', 'AwayTeam', 'FTR', 'HTWTD', 'ATWTD']]
结果验证
处理后第9行Leeds的HTWTD会更新为2,符合预期。整个流程完全使用Pandas原生函数,无需自定义复杂函数。
内容的提问来源于stack exchange,提问作者Stewart
相关产品推荐
相关产品推荐

