球门球长传准确率分析(Python案例)
下面通过一个完整的 Python 案例,演示如何统计和分析球门球长传准确率。

指标定义
| 指标 | 定义 |
|---|---|
| 球门球 | 门将开出的球门球(Goal Kick) |
| 长传 | 传球距离 ≥ 30 米(可自定义阈值) |
| 长传准确 | 传球成功到达本方队友脚下(未被拦截/出界) |
| 长传准确率 | 长传成功次数 / 长传总次数 × 100% |
数据准备(模拟数据)
import pandas as pd
import numpy as np
# 模拟:某门将本赛季球门球记录
np.random.seed(42)
data = {
"match_id": np.repeat(range(1, 11), 5), # 10场比赛,每场5次球门球
"distance_m": np.random.randint(15, 65, 50), # 传球距离(米)
"is_success": np.random.choice([1, 0], 50, p=[0.6, 0.4]), # 是否成功
"target_teammate": np.random.choice(["A", "B", "C", "D"], 50)
}
df = pd.DataFrame(data)
print(df.head())
核心计算代码
# 1. 定义长传阈值(>= 30米 视为长传)
LONG_PASS_THRESHOLD = 30
# 2. 标记长传
df["is_long_pass"] = df["distance_m"] >= LONG_PASS_THRESHOLD
# 3. 筛选长传记录
long_passes = df[df["is_long_pass"]]
# 4. 计算长传准确率
total_long = len(long_passes)
success_long = long_passes["is_success"].sum()
accuracy = success_long / total_long * 100
print(f"球门球长传总次数: {total_long}")
print(f"长传成功次数: {success_long}")
print(f"球门球长传准确率: {accuracy:.2f}%")
输出示例:
球门球长传总次数: 27
长传成功次数: 15
球门球长传准确率: 55.56%
进阶分析
按传球距离区间统计准确率
# 分箱:30-40m、40-50m、50m+
bins = [30, 40, 50, 100]
labels = ["30-40m", "40-50m", "50m+"]
long_passes = long_passes.copy()
long_passes["distance_bin"] = pd.cut(long_passes["distance_m"], bins=bins, labels=labels)
stats = long_passes.groupby("distance_bin", observed=True).agg(
total=("is_success", "count"),
success=("is_success", "sum"),
accuracy=("is_success", lambda x: x.mean() * 100)
).round(2)
print(stats)
按目标队友统计
by_target = long_passes.groupby("target_teammate").agg(
total=("is_success", "count"),
accuracy=("is_success", lambda x: x.mean() * 100)
).sort_values("accuracy", ascending=False).round(2)
print(by_target)
按比赛统计趋势
by_match = long_passes.groupby("match_id")["is_success"].mean() * 100
print(by_match.round(2))
可视化
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
# 距离区间准确率
stats["accuracy"].plot(kind="bar", ax=axes[0], color="steelblue")
axes[0].set_title("球门球长传准确率(按距离)")
axes[0].set_ylabel("准确率 (%)")
axes[0].set_ylim(0, 100)
# 各场次趋势
by_match.plot(kind="line", marker="o", ax=axes[1], color="darkorange")
axes[1].set_title("各场次球门球长传准确率")
axes[1].set_ylabel("准确率 (%)")
axes[1].set_ylim(0, 100)
plt.tight_layout()
plt.show()
真实数据接入(StatsBomb 示例)
如果使用 StatsBomb 开放数据,核心逻辑如下:
from statsbombpy import sb
# 读取比赛事件
events = sb.events(match_id=3788741)
# 筛选球门球
goal_kicks = events[events["pass_type"] == "Goal Kick"].copy()
# 计算传球距离(StatsBomb 单位为码,1码≈0.9144米)
goal_kicks["distance_m"] = goal_kicks["pass_length"] * 0.9144
# 长传筛选
long_gk = goal_kicks[goal_kicks["distance_m"] >= 30].copy()
# 准确率
accuracy = long_gk["pass_outcome"].isna().mean() * 100
print(f"球门球长传准确率: {accuracy:.2f}%")
说明:StatsBomb 中
pass_outcome为 NaN 表示传球成功。
小结
| 步骤 | 关键操作 |
|---|---|
| 1 | 筛选球门球事件 |
| 2 | 按距离阈值(如30m)筛选长传 |
| 3 | 用 is_success 字段统计成功率 |
| 4 | 可进一步按距离、目标、场次分组分析 |
| 5 | 可视化呈现趋势与分布 |
核心公式: $$\text{球门球长传准确率} = \frac{\text{长传成功次数}}{\text{长传总次数}} \times 100\%$$
如需针对具体数据源(如 WyScout、Opta、FIFA 数据)适配字段,可以告诉我数据结构,我再帮你调整代码。