守门员出击范围分析案例
下面通过一个完整的 Python 案例,演示如何分析守门员的出击范围,数据来源可以是 StatsBomb 开放数据(免费)。

分析思路
出击范围通常从以下维度衡量:
- 平均出击位置(距球门线距离)
- 出击热区分布(六码区/小禁区/大禁区/禁区外)
- 出击类型:角球出击、传中出击、清道夫式出击
- 成功率(出击是否成功夺球)
准备数据
使用 StatsBomb 免费开放数据(如女足欧洲杯、世界杯等赛事)。
import pandas as pd import numpy as np import matplotlib.pyplot as plt from statsbombpy import sb # 获取比赛列表 matches = sb.matches(competition_id=72, season_id=107) # 女足欧洲杯2022 match_id = matches.iloc[0]['match_id'] # 获取事件数据 events = sb.events(match_id=match_id)
筛选门将出击事件
StatsBomb 中门将相关事件主要有:
Goalkeeper类型下:Save、Punch、Catch、Collected、Smother、Keeper Sweeper
# 筛选门将事件
gk_events = events[events['type'] == 'Goalkeeper'].copy()
# 提取坐标
gk_events[['x', 'y']] = gk_events['location'].apply(
pd.Series
)
# 只看门将出击类动作(离开球门线的动作)
sweeper_types = ['Collected', 'Punch', 'Smother', 'Keeper Sweeper']
gk_sweeper = gk_events[gk_events['goalkeeper_type'].isin(sweeper_types)]
计算出击范围指标
# 1. 平均出击位置(x 越小越靠本方球门,StatsBomb 中 0=本方底线,120=对方底线)
avg_x = gk_sweeper['x'].mean()
# 2. 转换为距本方球门线的距离(1 StatsBomb 单位 ≈ 0.915 米)
distance_m = avg_x * 0.915
print(f"门将平均出击位置 x = {avg_x:.1f}(距球门线约 {distance_m:.1f} 米)")
# 3. 区域划分统计(球门线=0,六码区≈5.5m,小禁区≈18.3m,大禁区≈40.3m)
def zone(x):
if x < 6: return '球门线上'
elif x < 12: return '六码区'
elif x < 20: return '小禁区'
elif x < 44: return '大禁区'
else: return '禁区外'
gk_sweeper['zone'] = gk_sweeper['x'].apply(zone)
zone_dist = gk_sweeper['zone'].value_counts()
print(zone_dist)
可视化出击热区
from mplsoccer import Pitch
pitch = Pitch(pitch_type='statsbomb', line_color='black', half=True)
fig, ax = pitch.draw(figsize=(8, 6))
# 六边形热区(只看左半场)
pitch.kdeplot(
gk_sweeper['x'], gk_sweeper['y'],
ax=ax, fill=True, levels=50, cmap='Reds',
thresh=0.05
)
ax.set_title("门将出击位置热区")
plt.show()
对比两名门将
def analyze_gk(match_id, player_name):
ev = sb.events(match_id=match_id)
gk = ev[(ev['type']=='Goalkeeper') & (ev['player']==player_name)].copy()
gk[['x','y']] = gk['location'].apply(pd.Series)
sweeper = gk[gk['goalkeeper_type'].isin(sweeper_types)]
return {
'player': player_name,
'avg_x': sweeper['x'].mean(),
'max_x': sweeper['x'].max(),
'n_sweeper': len(sweeper),
'outside_box': (sweeper['x'] > 44).sum()
}
gk1 = analyze_gk(match_id, 'Christiane Endler')
gk2 = analyze_gk(match_id, 'Mary Earps')
print(pd.DataFrame([gk1, gk2]))
进阶指标(可选)
| 指标 | 计算方式 | 含义 |
|---|---|---|
| 出击成功率 | 成功夺球次数 / 总出击次数 | 判断鲁莽程度 |
| 出击范围标准差 | std(x) | 活动范围广度 |
| 出击纵深 | max(x) | 最远出击位置 |
| 场均出击次数 | 出击次数 / 出场数 | 主动程度 |
| 传中处理率 | 出击传中数 / 对手传中总数 | 覆盖能力 |
# 出击成功率示例(Punch、Collected 一般视为成功)
success_types = ['Collected', 'Punch', 'Catch']
gk = gk_events[gk_events['goalkeeper_type'].isin(sweeper_types)]
success_rate = gk['goalkeeper_type'].isin(success_types).mean()
print(f"出击成功率: {success_rate:.1%}")
常见数据源推荐
- StatsBomb(免费开放部分,含门将事件标签)
- FBref(进阶门将数据:Defensive Actions Outside Penalty Area 等)
- Wyscout(需付费)、SofaScore API
结论示例输出
门将平均出击位置 x≈13(距球门线约 12 米),大部分出击集中在小禁区边缘;出击传中和角球占比高,属于典型的"清道夫门将",防线压得较高。
如果你有具体的赛事 ID、数据文件(CSV/JSON)或想分析某位门将,我可以基于你的数据写出完整脚本。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播