后防线 xG Against 解读:Python 实战案例
xG Against 是什么
xG Against(xGA) 是对手在你方球门前创造的预期进球总和,用来量化"你的防线让对手获得了多少高质量机会"。

- xGA 越低 → 防线越稳固(不是靠门将神扑)
- xGA 高但失球少 → 门将超神 or 运气好,不可持续
- xGA 低但失球多 → 门将拖后腿 or 运气差
它比"失球数"更能反映防线的真实防守质量,因为它剥离了门将扑救和运气的干扰。
数据准备(用 understat 或 FBref)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from understat import Understat
import asyncio
# 方式1:直接从 FBref 抓取(以英超为例)
def get_team_defense_data(url):
tables = pd.read_html(url)
# FBref 的 squad defensive 表通常是第 2 个
df = tables[1]
df.columns = df.columns.droplevel(0) # 处理多层表头
return df
url = "https://fbref.com/en/comps/9/defense/2023-2024-Premier-League-Stats"
df = get_team_defense_data(url)
# 关注字段
cols = ['Squad', 'MP', 'Goals Against', 'xGA', 'xGA/90', 'PSxG', 'PSxG-GA']
df = df[cols].dropna()
df['GA-xGA'] = df['Goals Against'] - df['xGA'] # 关键差值
print(df.sort_values('xGA').head(10))
核心解读维度
单队 xGA 排名(基础层)
df_sorted = df.sort_values('xGA/90')
fig, ax = plt.subplots(figsize=(10, 10))
colors = ['#2ecc71' if x < df['xGA/90'].mean() else '#e74c3c' for x in df_sorted['xGA/90']]
ax.barh(df_sorted['Squad'], df_sorted['xGA/90'], color=colors)
ax.axvline(df['xGA/90'].mean(), color='black', linestyle='--', label='联赛平均')
ax.set_xlabel('xGA per 90 (越低越好)')
ax.set_title('各队防线 xGA/90 排名')
plt.legend()
plt.tight_layout()
plt.show()
解读:
- 绿色 = 防线强于联赛平均
- 红色 = 防线弱于联赛平均
- 与积分榜对比能看出"防线是否是球队成绩驱动因素"
GA vs xGA 差值分析(门将层)
fig, ax = plt.subplots(figsize=(8, 8))
ax.scatter(df['xGA'], df['Goals Against'], s=80, alpha=0.7)
# 画 y=x 参考线
lim = max(df['xGA'].max(), df['Goals Against'].max()) + 5
ax.plot([0, lim], [0, lim], 'k--', alpha=0.5, label='实际=预期')
for _, row in df.iterrows():
ax.annotate(row['Squad'], (row['xGA'], row['Goals Against']),
fontsize=7, alpha=0.7)
ax.set_xlabel('xGA(对手预期进球)')
ax.set_ylabel('GA(实际失球)')
ax.set_title('防线 xGA vs 实际失球')
ax.legend()
plt.tight_layout()
plt.show()
解读图:
- 点在参考线下方 → 门将/运气省了球(PSxG-GA 为正,好门将)
- 点在参考线上方 → 门将拖后腿(如 23/24 的 Onana 早期)
- 点离参考线远 → 结果有较大随机性 or 门将影响大
区分"防线质量" vs "门将扑救"
# FBref 中的关键指标
# PSxG (Post-Shot xG) = 射正球后的预期进球(已排除封堵)
# PSxG-GA > 0 表示门将扑救表现好于预期
df['goalkeeping_impact'] = df['PSxG'] - df['Goals Against']
df['defense_quality'] = df['xGA'] - df['PSxG'] # 越小说明防线把对手射门质量压制得越低
fig, ax = plt.subplots(figsize=(8, 8))
ax.scatter(df['defense_quality'], df['goalkeeping_impact'],
s=80, c=df['GA-xGA'], cmap='RdYlGn_r', edgecolor='k')
for _, row in df.iterrows():
ax.annotate(row['Squad'], (row['defense_quality'], row['goalkeeping_impact']),
fontsize=7)
ax.axvline(0, color='grey', lw=0.8)
ax.axhline(0, color='grey', lw=0.8)
ax.set_xlabel('防线质量(越右越差:让对手射门质量高)')
ax.set_ylabel('门将贡献(越上越好:扑救超预期)')
ax.set_title('防线 vs 门将:功劳归属')
plt.colorbar(ax.collections[0], label='GA - xGA')
plt.tight_layout()
plt.show()
四象限解读:
| 门将好 | 门将差 | |
|---|---|---|
| 防线差 | 靠门将硬撑 | 灾难区(丢球多) |
| 防线好 | 顶级防守 | 门将拖后腿 |
时间序列:防守趋势
# 用 understat 抓逐场数据
async def get_match_xga(team):
async with Understat('epl', '2023') as u:
return await u.get_team_results(team)
matches = asyncio.run(get_match_xga('Arsenal'))
df_m = pd.DataFrame(matches)
df_m['datetime'] = pd.to_datetime(df_m['datetime'])
df_m = df_m.sort_values('datetime')
# 计算滚动 5 场 xGA 均值
df_m['xGA_rolling'] = df_m['xGA'].rolling(5).mean()
plt.figure(figsize=(12, 5))
plt.plot(df_m['datetime'], df_m['xGA_rolling'], marker='o')
plt.axhline(df_m['xGA_rolling'].mean(), color='red', linestyle='--')'阿森纳赛季防线 xGA 滚动趋势(5场)')
plt.ylabel('xGA(滚动均值)')
plt.tight_layout()
plt.show()
解读:
- 曲线上升 → 防线恶化(伤病?战术调整?)
- 曲线下降 → 防线收紧(新援融入?阵型变化?)
进阶解读角度
对手强度调整
# 按对手强队/弱队分组
strong_teams = ['Man City', 'Arsenal', 'Liverpool', 'Aston Villa']
df['opponent_tier'] = df['Squad'].apply(
lambda x: 'Strong' if x in strong_teams else 'Weak')
# 但 xGA 是累计的,需要拆逐场数据来算
真正的解读:把 xGA 按对手强度拆分——对强队时 xGA 表现如何,比总 xGA 更能反映防线的"抗压能力"。
分阶段(定位球 vs 运动战)
FBref 提供:
xGA - Set Pieces(定位球)xGA - Open Play(运动战)xGA - Penalty KicksxGA - Corners/Free Kicks
set_piece_xga = df[['Squad', 'xGA', 'Set Piece xGA']].copy() set_piece_xga['sp_ratio'] = set_piece_xga['Set Piece xGA'] / set_piece_xga['xGA'] # 定位球 xGA 占比高的球队 → 防空/盯人训练不足
与 PPDA / 高位逼抢结合
# PPDA 越低 = 逼抢越凶 = 允许对手传球越少 # 高 PPDA + 低 xGA = 典型"低位防守"(如穆里尼奥风格) # 低 PPDA + 低 xGA = 典型"高位逼抢"(如克洛普风格)
报告模板(三段式解读)
对一支球队的防线 xGA 解读:
总体水平:本赛季 xGA/90 = 1.15,联赛第 4 低,防线处于前列。
与失球对比:GA = 42,xGA = 41.3,GA-xGA ≈ +0.7,说明门将表现基本符合预期,防线成果真实。
分解:定位球 xGA 占比 28% 偏高,运动战 xGA 联赛前 3 低,说明开放比赛防守优秀,但定位球是短板,可针对训练防空。
常见误区
| 误区 | 正确理解 |
|---|---|
| xGA 低 = 失球一定少 | ❌ 门将差/运气差会导致 GA 高 |
| 看单场 xGA 就下结论 | ❌ 有随机性,至少 5-10 场滚动 |
| 忽略对手强度 | ❌ 对弱队刷低 xGA 没说服力 |
| 忽视定位球 | ❌ FBref 分类数据要看 |
推荐工具组合
- 数据源:FBref(免费、分类细)、Understat(逐场 xG)、StatsBomb(付费、最细)
- Python 库:
pandas+matplotlib/plotly+mplsoccer(画图) - 可视化:雷达图对比多队、散点图看相关、热力图看分时段
如果你有具体某队/某赛季的数据,我可以帮你写一段针对性解读代码。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播