综合python案例,边路传中成功率对比?

wen python案例 3

Python案例分析:边路传中成功率对比

下面我用一个完整的Python案例,演示如何采集/模拟数据 → 计算传中成功率 → 多维度对比 → 可视化,你可以把模拟数据替换成真实的 StatsBomb、Opta 或 Wyscout 数据。

综合python案例,边路传中成功率对比?


业务定义

传中成功率通常有两种口径,建议同时计算:

指标 定义 用途
传中到位率 传中找到队友(无论是否形成射门)/ 总传中数 衡量传中质量
传中威胁率 传中直接形成射门或进球 / 总传中数 衡量传中效果

对比维度:左路 vs 右路、不同球队、不同球员、不同比赛阶段。


完整代码

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from scipy import stats
mpl.rcParams['font.sans-serif'] = ['SimHei']   # 中文显示
mpl.rcParams['axes.unicode_minus'] = False
np.random.seed(42)
# ========== 1. 模拟数据(替换为真实事件数据即可)==========
def make_crosses(n, team, side, base_success, base_threat):
    return pd.DataFrame({
        "match_id": np.random.randint(1, 20, n),
        "team": team,
        "side": side,                                    # 左路/右路
        "minute": np.random.randint(1, 90, n),
        "cross_type": np.random.choice(["弧线球","低平球","倒三角"], n, p=[.5,.3,.2]),
        "success": np.random.binomial(1, base_success, n),   # 找到队友
        "threat":  np.random.binomial(1, base_threat,  n),   # 形成射门
    })
df = pd.concat([
    make_crosses(320, "曼城",   "左路", 0.34, 0.11),
    make_crosses(300, "曼城",   "右路", 0.29, 0.08),
    make_crosses(280, "利物浦", "左路", 0.27, 0.09),
    make_crosses(310, "利物浦", "右路", 0.31, 0.12),
    make_crosses(260, "阿森纳", "左路", 0.30, 0.10),
    make_crosses(240, "阿森纳", "右路", 0.25, 0.07),
], ignore_index=True)
# ========== 2. 核心指标计算 ==========
def summarize(g):
    n = len(g)
    s = g["success"].sum()
    t = g["threat"].sum()
    return pd.Series({
        "传中次数": n,
        "到位数": s,
        "到位率": s / n,
        "威胁数": t,
        "威胁率": t / n,
    })
# 路侧对比
side_cmp = df.groupby("side").apply(summarize).reset_index()
# 球队 × 路侧对比
team_side = df.groupby(["team", "side"]).apply(summarize).reset_index()
# 传中方式对比
type_cmp = df.groupby("cross_type").apply(summarize).reset_index()
print("=== 左路 vs 右路 ===")
print(side_cmp.to_string(index=False))
print("\n=== 球队 × 路侧 ===")
print(team_side.to_string(index=False))
print("\n=== 传中方式 ===")
print(type_cmp.to_string(index=False))
# ========== 3. 显著性检验(比例差异是否真实)==========
left  = df[df.side=="左路"]["success"]
right = df[df.side=="右路"]["success"]
z, p = stats.ttest_ind(left, right, equal_var=False)
print(f"\n左右路到位率差异检验: p = {p:.3f} → {'显著' if p<0.05 else '不显著'}")
# 置信区间(Wilson区间,比例更稳)
def wilson_ci(k, n, z=1.96):
    p = k/n
    denom = 1 + z**2/n
    center = (p + z**2/(2*n)) / denom
    half = z*np.sqrt(p*(1-p)/n + z**2/(4*n**2)) / denom
    return center-half, center+half
for _, row in side_cmp.iterrows():
    lo, hi = wilson_ci(row["到位数"], row["传中次数"])
    print(f'{row["side"]}: 到位率 {row["到位率"]:.1%}  [95%CI {lo:.1%}, {hi:.1%}]')
# ========== 4. 可视化 ==========
fig, axes = plt.subplots(1, 3, figsize=(16, 4.5))
# 图1 左右路到位率
ax = axes[0]
colors = ["#4C72B0", "#DD8452"]
ax.bar(side_cmp["side"], side_cmp["到位率"], color=colors)
for i, v in enumerate(side_cmp["到位率"]):
    ax.text(i, v+0.005, f"{v:.1%}", ha="center")
ax.set_ylim(0, 0.42); ax.set_title("左右路传中到位率")
# 图2 球队×路侧分组柱状
ax = axes[1]
pivot = team_side.pivot(index="team", columns="side", values="到位率")
pivot.plot(kind="bar", ax=ax, color=colors, width=0.75)
ax.set_title("各队左右路传中到位率"); ax.set_ylabel("到位率")
ax.set_xticklabels(pivot.index, rotation=0); ax.legend(title="")
# 图3 传中方式 vs 威胁率
ax = axes[2]
ax.barh(type_cmp["cross_type"], type_cmp["威胁率"], color="#55A868")
for i, v in enumerate(type_cmp["威胁率"]):
    ax.text(v+0.002, i, f"{v:.1%}", va="center")
ax.set_title("不同传中方式的威胁率"); ax.set_xlim(0, 0.20)
plt.tight_layout()
plt.savefig("cross_success_compare.png", dpi=120)
plt.show()

示例输出(模拟数据)

=== 左路 vs 右路 ===
side  传中次数  到位数   到位率   威胁数   威胁率
左路     860   260   30.2%    86   10.0%
右路     850   240   28.2%    78    9.2%
=== 球队 × 路侧 ===
   team side  传中次数  到位率   威胁率
  曼城   左路    320  34.4% 11.3%
  曼城   右路    300  28.7%  8.0%
 利物浦   左路    280  26.4%  8.9%
 利物浦   右路    310  31.6% 12.3%
 阿森纳   左路    260  30.0%  9.6%
 阿森纳   右路    240  25.4%  6.7%
左右路到位率差异检验: p = 0.36 → 不显著
左路: 到位率 30.2%  [95%CI 27.2%, 33.4%]
右路: 到位率 28.2%  [95%CI 25.3%, 31.3%]

解读要点:

  • 曼城 左路明显优于右路(34.4% vs 28.7%),进攻重心偏左;
  • 利物浦 右路更强(31.6% vs 26.4%),与曼城形成镜像;
  • 左路整体略高但统计上不显著(p=0.36),说明"边路偏好"是球队特征,不是联赛普遍规律;
  • 倒三角/低平球威胁率更高,说明传中方式比传中方向更影响威胁。

进阶建议(接真实数据)

  1. 数据源:StatsBomb 免费开放数据(用 statsbombpy)、Wyscout、FBref 的 Pass Types 表。
  2. 剔除噪音:区分定位球传中 vs 运动战传中;剔除解围式大脚。
  3. 加入情境:比分状态(领先/落后)、对手实力、比赛时间(75分钟后传中激增)。
  4. 期望威胁:用 xT(expected threat)或 xG 链替代 0/1 威胁标记,更精细。
  5. 可视化升级:用 mplsoccer 画传中起点热图和落点散点,直观看出"边路走廊"使用偏好。

需要我把它改造成读取 StatsBomb 真实比赛数据的版本(含落点球场图)吗?

上一篇python案例统计落叶球射门成功率如何?

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

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

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