python案例怎么看两队边路突破能力对比?

wen python案例 2

两队边路突破能力对比

下面我用一个完整的 Python 案例,演示如何从比赛事件数据中对比两队的边路突破能力。

python案例怎么看两队边路突破能力对比?

核心思路

边路突破能力可从以下几个维度量化:

维度 说明
边路带球次数 在边路区域(x < 20 或 x > 80,或用 y 坐标判断)的带球事件
成功过人次数 边路区域的 dribble 成功事件
边路传中次数 从边路发起的 cross
突破成功率 成功过人 / 尝试过人
推进距离 边路带球带来的纵向推进

完整代码示例

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
# ========== 1. 造一份模拟数据(StatsBomb 风格) ==========
np.random.seed(42)
def gen_team_events(team, side_bias, n=400):
    """side_bias: 该队偏向左路(-1)、右路(1)或均衡(0)"""
    events = []
    for _ in range(n):
        # y 坐标 0~80(宽),x 坐标 0~120(长)
        y = np.random.uniform(0, 80)
        x = np.random.uniform(20, 100)
        # 判断是否在边路(上下 20 米区域)
        if y < 20 or y > 60:
            zone = 'wing'
        else:
            zone = 'center'
        # 边路突破时成功率略高
        success = np.random.rand() < (0.55 if zone == 'wing' else 0.45)
        events.append({
            'team': team,
            'type': 'dribble',
            'x': x,
            'y': y,
            'zone': zone,
            'success': success,
            'progress': x if success else 0   # 简化:推进距离
        })
    return events
events = gen_team_events('Team_A', -1, 400) + gen_team_events('Team_B', 1, 400)
df = pd.DataFrame(events)
# 只看边路突破事件
wing = df[df['zone'] == 'wing']
# ========== 2. 计算关键指标 ==========
def calc_wing_metrics(g):
    attempts = len(g)
    success = g['success'].sum()
    return pd.Series({
        '边路突破尝试': attempts,
        '边路突破成功': success,
        '成功率(%)': round(success / attempts * 100, 1) if attempts else 0,
        '平均推进(m)': round(g.loc[g['success'], 'progress'].mean(), 1) if success else 0,
        # 左/右路分布
        '左路占比(%)': round((g['y'] < 20).mean() * 100, 1),
        '右路占比(%)': round((g['y'] > 60).mean() * 100, 1),
    })
comparison = wing.groupby('team').apply(calc_wing_metrics, include_groups=False)
print("=== 边路突破能力对比 ===")
print(comparison.to_string())

输出示例:

=== 边路突破能力对比 ===
        边路突破尝试  边路突破成功  成功率(%)  平均推进(m)  左路占比(%)  右路占比(%)
team
Team_A       167        95     56.9       58.3       50.9       49.1
Team_B       161        88     54.7       57.2       47.8       52.2

可视化对比

# 设置中文
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
# 1. 成功率柱状图
comparison['成功率(%)'].plot(kind='bar', ax=axes[0], color=['#e74c3c','#3498db'])
axes[0].set_title('边路突破成功率')
axes[0].set_ylabel('%')
axes[0].bar_label(axes[0].containers[0])
# 2. 左/右路分布堆叠图
comparison[['左路占比(%)','右路占比(%)']].plot(
    kind='bar', stacked=True, ax=axes[1], color=['#f39c12','#2ecc71'])
axes[1].set_title('进攻边路偏好(占比)')
axes[1].set_ylabel('%')
# 3. 突破走廊热图(按 y 坐标分 8 个区段)
def wing_lanes(g):
    lanes = pd.cut(g['y'], bins=np.arange(0, 81, 10), labels=False)
    return lanes.value_counts().sort_index()
lane_a = wing_lanes(wing[wing['team']=='Team_A'])
lane_b = wing_lanes(wing[wing['team']=='Team_B'])
lane_df = pd.DataFrame({'Team_A': lane_a, 'Team_B': lane_b}).fillna(0)
lane_df.plot(kind='bar', ax=axes[2], color=['#e74c3c','#3498db'])
axes[2].set_title('边路走廊活动分布(y坐标分段)')
axes[2].set_xlabel('y坐标区段(0=左路,7=右路)')
plt.tight_layout()
plt.show()

进阶:用真实数据(StatsBomb)

若要接入真实数据,把造数据部分换成:

from statsbombpy import sb
matches = sb.matches(competition_id=11, season_id=90)  # 示例
events = sb.events(match_id=matches.iloc[0]['match_id'])
# 筛选带球事件,提取坐标
dribbles = events[events['type'] == 'Dribble'].copy()
dribbles[['x','y']] = dribbles['location'].apply(pd.Series)

分析结论要点

  1. 谁更依赖边路:边路突破尝试次数多说明战术侧重
  2. 谁效率更高:成功率 + 平均推进距离
  3. 哪条边更强:左/右路占比 + 走廊分布图
  4. 结合对手:若 A 队右路突破多但 B 队左路防守强,则 A 该换边

需要我针对真实赛事数据接口(StatsBomb / Wyscout / Opta)或更细的指标(xT、突破后射门转化)再展开吗?

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

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