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

Pandas 如何按条件筛选后每40场统计Team_1进球数并绘制年度变化图

实现按固定场次窗口求和的完整方案

原代码的核心问题定位

  • 代码筛选出Team_1参与的有效比赛后,仅对前40行计算了一次固定总和,再把这个单值赋值给整列的GoalSum,导致绘图时所有点的y值完全一致,最终呈现为水平直线
  • 未按有效比赛的序列做独立切分,直接基于全量DataFrame的行索引做切片,会把无Team_1参与的无效比赛误计入计数序列

分步实现逻辑

  1. 过滤有效比赛数据:首先从原始DataFrame中筛出所有满足「主队/客队为Team_1、且Team_1 Goals不为-1」的行,按比赛日期升序排序,确保比赛时序正确。非Team_1参与的无效比赛直接排除,不参与后续计数和求和。
  2. 按固定场次切分计算块:对排序后的有效比赛序列,每40场划分为一个独立计算单元——通过整数除法给每一场有效比赛分配组号,确保连续40场有效比赛归入同一组:
    valid_matches['group_id'] = np.arange(len(valid_matches)) // 40
    
    这个逻辑和你给出的3场为一个计算单元的示例完全匹配:
    • 第0、1、2号有效比赛(对应原表索引0、1、2)会分到同一组,组内求和为0+3+1=4,将这个值回填到组内最后一行(原表索引2)的GoalSum列
    • 第3、4、5号有效比赛(对应原表索引3、4、5)会分到下一组,组内求和为2+2+1=5,将这个值回填到组内最后一行(原表索引5)的GoalSum列
  3. 计算组内求和并回填:对每个group_id分组计算Team_1 Goals的总和,把结果映射回原始DataFrame的对应位置,非计算块结尾的行GoalSum留空即可。
  4. 绘图实现:提取所有GoalSum非空的行作为绘图点,x轴取对应行的Date年份,y轴取计算得到的GoalSum值,绘制的折线就会随每个计算块的进球总和波动,不会出现水平直线的问题。

可直接运行的示例代码

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 预处理原始数据
# 按需求过滤有效比赛
valid_mask = ((df["HomeTeam"] == "Team_1") | (df["OpponentTeam"] == "Team_1")) & (df["Team_1 Goals"] != -1)
valid_matches = df[valid_mask].sort_values("Date").copy()  # 按日期排序保证时序
# 初始化全量DataFrame的GoalSum列
df["GoalSum"] = np.nan

# 每40场为一组计算求和
WINDOW_SIZE = 40  # 按需求调整窗口大小,如示例要3场就改成3
valid_matches["group_id"] = np.arange(len(valid_matches)) // WINDOW_SIZE
# 计算每个组的进球总和
group_sum = valid_matches.groupby("group_id")["Team_1 Goals"].sum()

# 把每个组的总和回填到对应组最后一行的原表位置
for gid, total_goal in group_sum.items():
    current_group = valid_matches[valid_matches["group_id"] == gid]
    last_match_original_index = current_group.index[-1]
    df.loc[last_match_original_index, "GoalSum"] = total_goal

# 绘制折线图
# 仅取有GoalSum值的行作为绘图点
plot_data = df.dropna(subset=["GoalSum"]).copy()
plot_data["year"] = pd.to_datetime(plot_data["Date"]).dt.year

plt.plot(plot_data["year"], plot_data["GoalSum"], marker='o')
plt.xlabel("年份")
plt.ylabel("每40场有效比赛进球总和")
plt.show()

效果验证

用你给出的3场窗口的示例数据运行代码,把WINDOW_SIZE设为3,最终输出的GoalSum列会和预期结果完全一致:原表索引2的位置回填4,原表索引5的位置回填5,其余位置留空,绘图时只会提取这两个有值的点生成折线。结合你提到的「Team_1每年参赛超过40场」的前提,最终生成的折线会随每40场的进球数波动,不会出现水平直线的问题。

内容的提问来源于stack exchange,提问作者Mr. Engineer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.28 01:15:04