如何使用pandas计算电竞战队各周X场历史得分滚动平均值
原有代码问题
- 计算结果未赋值:你执行了
groupby和rolling计算,但没有将结果赋值给临时表的对应字段,计算结果直接被丢弃,原数据没有任何变化 - 分组维度错误:你需要的是单个战队的历史场次滚动平均,应该以战队为分组维度,而非按周分组,按周分组会导致窗口仅在单周内计算,无法得到跨周的历史平均
- 数据筛选逻辑存在隐式依赖:你当前的数据集恰好将每场比赛存为双向两行(主队、客队各一条),但如果后续数据没有双向存储,仅筛选
Team列等于目标战队的行,会丢失该战队作为客队的参赛记录 - 排序后索引未重置:
sort_values后没有重置索引,后续拼接时容易出现索引冲突问题
正确实现方案
实现思路
- 先将原始双向存储的比赛数据,转换为每行对应单个战队单场参赛记录的统一结构,避免丢失客队参赛数据
- 按战队分组后,按周次升序排序
- 对指定的多个特征列执行滚动窗口平均,前N-1场自动返回空值
- 封装为可自定义窗口大小、特征列的通用函数
完整代码
import pandas as pd def calc_team_rolling_avg(df, window_size, feature_cols=['Team Points', 'Vs Points']): # 1. 转换数据格式:将每场比赛拆为两个战队的独立参赛记录 df_home = df[['Week', 'Team', 'Vs', 'Team Points', 'Vs Points']].rename( columns={'Team': 'Team', 'Vs': 'Opponent', 'Team Points': 'Points', 'Vs Points': 'Opponent Points'} ) df_away = df[['Week', 'Vs', 'Team', 'Vs Points', 'Team Points']].rename( columns={'Vs': 'Team', 'Team': 'Opponent', 'Vs Points': 'Points', 'Team Points': 'Opponent Points'} ) all_match_records = pd.concat([df_home, df_away], ignore_index=True) # 2. 按战队分组、按周排序后计算滚动平均 all_match_records = all_match_records.sort_values(by=['Team', 'Week'], ignore_index=True) # 对每个特征生成滚动平均列 for col in feature_cols: all_match_records[f'{col}_rolling_avg_{window_size}'] = all_match_records.groupby('Team')[col].transform( lambda x: x.rolling(window=window_size, min_periods=window_size).mean() ) return all_match_records # 测试用例 if __name__ == '__main__': # 读取剪贴板数据 df = pd.read_clipboard() # 计算窗口为2的滚动平均 res = calc_team_rolling_avg(df, window_size=2) print(res.head(10)) # 如果需要输出仅包含Week、Team、对应平均字段的结构,可自行筛选列 # res_simple = res[['Week', 'Team', 'Points_rolling_avg_2']]
输出说明
- 每个战队的前
window_size-1场比赛的滚动平均字段会自动填充为空,符合需求 - 自动适配战队缺赛的情况:仅按实际参赛场次计算滚动窗口,不会用空周填充
- 支持自定义
feature_cols参数传入需要计算的10个特征,自动批量生成对应滚动平均字段
内容的提问来源于stack exchange,提问作者artemis
相关产品推荐
相关产品推荐

