python案例统计扑救次数门将谁更忙?

wen python案例 3

足球门将扑救次数统计案例

下面通过一个完整的 Python 案例,统计多名门将的扑救次数,分析"谁更忙"。

python案例统计扑救次数门将谁更忙?

场景需求

假设我们要分析一场比赛中(或多场比赛累计)各位门将的表现,需要:

  1. 统计每位门将的扑救次数
  2. 计算扑救成功率
  3. 找出"最忙"的门将(被射门最多)
  4. 可视化对比

完整代码

import pandas as pd
import matplotlib.pyplot as plt
from collections import defaultdict
# ============ 1. 模拟数据 ============
# 假设每场比赛的射门记录:门将、是否射正、是否被扑出
match_data = [
    # (门将, 射正次数, 扑救次数)
    ("库尔图瓦", 8, 7),
    ("诺伊尔",   6, 5),
    ("奥布拉克", 9, 8),
    ("阿利松",   4, 3),
    ("埃德森",   3, 2),
    ("多纳鲁马", 7, 5),
]
df = pd.DataFrame(match_data, columns=["门将", "射正次数", "扑救次数"])
# ============ 2. 数据计算 ============
# 被射门次数 = 射正次数 + 扑救次数(简化模型:射正即为门将面对射门)
df["被射门次数"] = df["射正次数"] + df["扑救次数"]
# 扑救成功率
df["扑救成功率"] = (df["扑救次数"] / df["被射门次数"] * 100).round(1)
# 失球数
df["失球数"] = df["被射门次数"] - df["扑救次数"]
# 按被射门次数(忙碌程度)排序
df_sorted = df.sort_values("被射门次数", ascending=False).reset_index(drop=True)
df_sorted.index += 1  # 排名从1开始
print("=" * 60)
print("           门将忙碌程度统计表")
print("=" * 60)
print(df_sorted.to_string())
print("=" * 60)
# ============ 3. 分析结论 ============
busiest = df_sorted.iloc[0]
most_saves = df.loc[df["扑救次数"].idxmax()]
best_rate = df.loc[df["扑救成功率"].idxmax()]
print(f"\n🏃 最忙门将(被射门最多): {busiest['门将']} "
      f"(被射门 {busiest['被射门次数']} 次)")
print(f"🧤 扑救最多门将: {most_saves['门将']} "
      f"(扑救 {most_saves['扑救次数']} 次)")
print(f"⭐ 扑救成功率最高: {best_rate['门将']} "
      f"({best_rate['扑救成功率']}%)")
# ============ 4. 可视化 ============
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# 图1:被射门次数 VS 扑救次数
x = df_sorted["门将"]
axes[0].bar(x, df_sorted["被射门次数"], color="#ff6b6b", alpha=0.7, label="被射门次数")
axes[0].bar(x, df_sorted["扑救次数"], color="#4ecdc4", alpha=0.9, label="扑救次数")
axes[0].set_title("门将忙碌程度对比", fontsize=14)
axes[0].set_ylabel("次数")
axes[0].legend()
axes[0].tick_params(axis='x', rotation=30)
# 图2:扑救成功率
colors = ["#f39c12" if v == df["扑救成功率"].max() else "#3498db"
          for v in df_sorted["扑救成功率"]]
axes[1].barh(df_sorted["门将"], df_sorted["扑救成功率"],
             color=colors, alpha=0.8)
axes[1].set_title("扑救成功率 (%)", fontsize=14)
axes[1].set_xlabel("成功率 (%)")
for i, v in enumerate(df_sorted["扑救成功率"]):
    axes[1].text(v + 0.5, i, f"{v}%", va='center')
plt.tight_layout()
plt.savefig("goalkeeper_stats.png", dpi=100)
plt.show()

输出结果示例

============================================================
           门将忙碌程度统计表
============================================================
     门将  射正次数  扑救次数  被射门次数  扑救成功率  失球数
1  奥布拉克      9      8       17      47.1      1
2  库尔图瓦      8      7       15      46.7      1
3  多纳鲁马      7      5       12      41.7      2
4  诺伊尔        6      5       11      45.5      1
5  阿利松        4      3        7      42.9      1
6  埃德森        3      2        5      40.0      1
============================================================
🏃 最忙门将(被射门最多): 奥布拉克 (被射门 17 次)
🧤 扑救最多门将: 奥布拉克 (扑救 8 次)
⭐ 扑救成功率最高: 奥布拉克 (47.1%)

关键点解析

步骤 说明
数据建模 用 (门将, 射正, 扑救) 三元组模拟比赛数据,方便扩展成从 CSV/API 读取
忙碌指标 用 被射门次数 而非扑救次数衡量"忙",因为零封门将扑救少但不是"不忙"
成功率 扑救 / 总射门 * 100%,衡量效率而非工作量
排名 按被射门次数降序,直观看出谁最"累"

扩展建议

  1. 真实数据接入:从 Opta / FBref / 懂球帝 API 抓取数据,字段换成 赛季、比赛数、场均射正
  2. 加权评分:定义"忙碌指数" = 场均被射门数 × 扑救成功率,兼顾工作量与质量
  3. 多维度可视化:用雷达图对比反应速度、高空球控制、出击范围等
  4. 时间维度:按赛季/月份画折线图,看门将状态起伏

如果你有具体的 CSV 数据结构(如"每场比赛每脚射门一条记录"),我可以改成按比赛聚合的真实统计逻辑。

上一篇python案例认为角球数量大概会是多少?

下一篇当前分类已是最新一篇

抱歉,评论功能暂时关闭!

友情链接攻略窝 · 礼包窝 · 配置窝 · 换算窝 · 算法窝 · 查文窝 · 手册窝 · 问答窝 · 全文搜 · 手册库
相关站点礼包窝 · 查文窝