用Python分析两队中场控制力对比
中场控制力是足球分析中的核心指标,下面给出一个完整的案例框架,从数据获取 → 指标构建 → 可视化对比。

中场控制力的核心指标
| 维度 | 指标 | 说明 |
|---|---|---|
| 控球 | 控球率、中场三区传球占比 | 球权掌握 |
| 传球 | 传球成功率、向前传球比例、推进距离 | 组织能力 |
| 对抗 | 中场抢断、拦截、夺回球权次数 | 防守控制 |
| 推进 | Progressive Passes、Carries | 由守转攻 |
| 位置 | 中场球员平均触球热区 | 空间控制 |
模拟数据示例(可直接运行)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 中文显示
matplotlib.rcParams['axes.unicode_minus'] = False
# 模拟两队中场数据(真实场景可用 StatsBomb / FBref / Opta 抓取)
data = {
'指标': ['控球率(%)', '中场传球成功率(%)', '向前传球占比(%)',
'中场抢断次数', '拦截次数', '夺回球权次数',
'渐进传球(Prog Passes)', '中场触球占比(%)'],
'A队': [58, 89, 34, 12, 9, 41, 62, 55],
'B队': [42, 82, 27, 8, 6, 33, 45, 45],
}
df = pd.DataFrame(data).set_index('指标')
# 归一化到 0-1 便于雷达图对比
norm = df.div(df.max(axis=1), axis=0)
# ---------- 雷达图 ----------
labels = df.index.tolist()
angles = np.linspace(0, 2*np.pi, len(labels), endpoint=False).tolist()
angles += angles[:1]
fig, ax = plt.subplots(figsize=(7, 7), subplot_kw=dict(polar=True))
for team, color in zip(['A队', 'B队'], ['#e63946', '#1d3557']):
vals = norm[team].tolist()
vals += vals[:1]
ax.plot(angles, vals, color=color, linewidth=2, label=team)
ax.fill(angles, vals, color=color, alpha=0.25)
ax.set_xticks(angles[:-1])
ax.set_xticklabels(labels, fontsize=9)
ax.set_yticklabels([])
ax.set_title('两队中场控制力雷达对比', fontsize=14, pad=20)
ax.legend(loc='upper right', bbox_to_anchor=(1.25, 1.1))
plt.tight_layout()
plt.show()
# ---------- 综合控制力指数 ----------
# 加权评分(权重可根据战术偏好调整)
weights = {
'控球率(%)': 0.15, '中场传球成功率(%)': 0.20, '向前传球占比(%)': 0.15,
'中场抢断次数': 0.10, '拦截次数': 0.10, '夺回球权次数': 0.10,
'渐进传球(Prog Passes)': 0.15, '中场触球占比(%)': 0.05,
}
score = (norm.T * pd.Series(weights)).T.sum()
print("\n综合中场控制力指数:")
print(score.round(3))
真实数据获取路径
# 方案1:FBref(免费,需爬虫或直接用 soccerdata 库) # pip install soccerdata import soccerdata as sd fbref = sd.FBref(leagues="ENG-Premier League", seasons="2023-2024") stats = fbref.read_team_season_stats(stat_type="passing") # 再筛选 midfield 三区数据 # 方案2:StatsBomb 免费开放数据(事件级,可精确划分中场区域) # from statsbombpy import sb # events = sb.events(match_id=xxxx) # 通过 event['location'] 的 x 坐标过滤 1/3~2/3 区域 # 方案3:Understat(xG/xA 视角)
进阶分析思路
- 传球网络图(Pass Network):用
mplsoccer画中场球员间的传球网络,节点大小=触球数,边粗细=传球次数,看谁是"枢纽"。
from mplsoccer import Pitch pitch = Pitch(pitch_type='statsbomb') fig, ax = pitch.draw() # 绘制球员位置 + 传球连线(需事件数据)
-
Progressive Passes 地图:把两队所有渐进传球起终点画在半场图上,看谁更能"穿透"中场。
-
中场三区夺回球权热图:
mplsoccer的heatmap直接可视化,对比两队在中圈附近的压迫强度。 -
PPDA(防守压迫强度):
对方传球数 / 己方防守动作数,越低说明中场压迫越强。 -
Zone 14(禁区弧顶)传球次数:衡量中场创造力落点。
快速结论解读示例
综合指数:A队 0.87 vs B队 0.63
→ A队中场控制力明显占优,主要体现在传球成功率和渐进传球上
→ B队若想抗衡,应压缩中场空间、提高 PPDA 压迫强度
如果你有具体的比赛数据(CSV/事件数据),可以把字段发我,我帮你定制指标计算和可视化脚本。