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

Python Pandas:计算选手身份动态切换的多列滚动平均值

修正网球选手滚动发球得分平均值计算代码

问题背景

你的网球数据集中选手会在P1和P2身份间切换,直接按P1/P2分组计算滚动平均会因为同一选手跨列分布导致索引冲突,出现ValueError: cannot reindex from a duplicate axis错误。

原始数据示例

假设你的数据结构如下:

DateP1P2P1_1stWonP2_1stWon
2023-01-01AB86
2023-01-02BA79
2023-01-03AC105
2023-01-04CA68

期望输出

需要得到每个选手对应身份下的滚动发球得分平均值(以窗口大小2为例):

DateP1P2P1_1stWonP2_1stWonP1_rolling_avgP2_rolling_avg
2023-01-01AB868.06.0
2023-01-02BA796.58.5
2023-01-03AC1059.55.0
2023-01-04CA685.58.5

修正代码

import pandas as pd

# 读取并预处理数据
df = pd.read_csv('tennis_data.csv')
df['Date'] = pd.to_datetime(df['Date'])

# 1. 将宽格式数据转为长格式,整合所有选手的参赛记录
long_format = pd.melt(
    df,
    id_vars=['Date'],
    value_vars=['P1', 'P2'],
    var_name='Player_Role',
    value_name='Player_Name'
)
# 匹配对应角色的发球得分
long_format['1stWon'] = long_format.apply(
    lambda x: df.loc[x.name, f"{x['Player_Role']}_1stWon"],
    axis=1
)

# 2. 按选手分组计算滚动平均值(窗口大小可自行调整)
long_format['rolling_avg'] = long_format.groupby('Player_Name')['1stWon'].rolling(
    window=2, min_periods=1, on='Date'
).mean().reset_index(level=0, drop=True)

# 3. 拆分回原角色的滚动平均并合并到原数据
p1_avg = long_format[long_format['Player_Role'] == 'P1']['rolling_avg'].rename('P1_rolling_avg')
p2_avg = long_format[long_format['Player_Role'] == 'P2']['rolling_avg'].rename('P2_rolling_avg')

final_df = pd.concat([df, p1_avg, p2_avg], axis=1)

# 输出结果
print(final_df)

关键逻辑说明

  1. 长格式转换:用pd.melt把P1/P2列拆分为角色和选手名,让同一选手的所有参赛记录(无论作为P1还是P2)都归到同一分组下,解决跨列分组的问题。
  2. 滚动平均计算:基于Date排序后按选手分组计算滚动平均,min_periods=1确保第一条记录能输出自身数值。
  3. 合并回原数据:将长格式中对应P1/P2的滚动平均拆分出来,与原数据按索引合并,保证结果行与原数据完全对应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 03:40:22