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

wen python案例 2

本文目录导读:

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

  1. 核心思路
  2. 方案一:基于球员级(Pandas + Seaborn/Matplotlib)
  3. 方案二:基于事件流(Pandas + 条件筛选)
  4. 方案三:热力图可视化(Matplotlib + 散点图)
  5. 总结:如何选择方案?

这是一个非常具体的足球数据分析问题,在Python中,要对比两队的边路突破能力,核心在于找到能够量化“边路”和“突破”的数据指标,并进行可视化对比。

由于你大概率是在做数据分析项目足球数据挖掘,下面提供三种不同数据来源和颗粒度的解决方案,你可以根据自己掌握的数据类型,选择最适合的一种。

核心思路

  1. 定义边路区域:通常将球场宽度三等分或按左右球员的活动热区划分(左路、中路、右路)。
  2. 定义突破:成功过人(Dribble / Take-on)、传中(Cross)、突破造犯规、进入禁区的次数等。
  3. 可视化对比:雷达图、条形图、气泡图或热力图是首选。

基于球员级(Pandas + Seaborn/Matplotlib)

这是最常见的场景,假设你有一份包含球员比赛数据的DataFrame(例如从StatsBomb、Wyscout或CSV文件获取)。

数据假设结构:

team player passes_into_box successful_dribbles cross_accuracy area
曼城 Foden 12 8 35 Left
曼联 Rashford 10 7 40 Left
曼城 Mahrez 15 6 45 Right
曼联 Antony 8 5 30 Right

代码示例:雷达图对比两队边路核心

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from math import pi
# 1. 加载数据
df = pd.read_csv('match_data.csv')  # 你的数据
# 2. 筛选边路球员 (假设有 area 列: Left/Right)
df_wide = df[df['area'].isin(['Left', 'Right'])]
# 3. 聚合到球队级别,计算边路突破相关指标
team_stats = df_wide.groupby('team').agg({
    'successful_dribbles': 'sum',  # 成功过人总数
    'passes_into_box': 'sum',      # 传入禁区次数
    'cross_accuracy': 'mean',      # 传中成功率
    'fouls_won_wide': 'sum'        # 边路造犯规
}).reset_index()
# 4. 雷达图:对比两队边路综合能力
categories = ['成功过人', '传入禁区', '传中成功率', '边路造犯规']
# 归一化 (Min-Max) 以便在同一张图显示
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
team_stats[categories] = scaler.fit_transform(team_stats[categories].values)
# 设置雷达图
N = len(categories)
angles = [n / float(N) * 2 * pi for n in range(N)]
angles += angles[:1]  # 闭合
fig, ax = plt.subplots(figsize=(8, 8), subplot_kw=dict(polar=True))
colors = ['#FF6347', '#4682B4']  # 两队颜色
for idx, row in team_stats.iterrows():
    values = row[categories].tolist()
    values += values[:1]  # 闭合
    ax.plot(angles, values, 'o-', linewidth=2, label=row['team'], color=colors[idx])
    ax.fill(angles, values, alpha=0.25, color=colors[idx])
ax.set_xticks(angles[:-1])
ax.set_xticklabels(categories, fontsize=11)
ax.set_ylim(0, 1.1)'两队边路突破能力雷达对比', size=15, pad=20)
plt.legend(loc='upper right', bbox_to_anchor=(1.2, 1.1))
plt.show()

解读: 雷达图覆盖面积越大,该项能力越强,如果球队A的“成功过人”和“传入禁区”数值远高于球队B,说明其边路突破威胁更大。


基于事件流(Pandas + 条件筛选)

如果你有逐秒事件数据(Event Data),例如WhoScored或Opta数据,可以精确统计发生在边路的、导致威胁的事件。

数据假设结构:

event_id team event_type start_x start_y end_x end_y outcome
1 队A Dribble 15 5 30 4 Successful
2 队B Cross 20 3 50 6 Accurate
...

代码示例:统计有效边路突破

# 定义边路区域 (假设球场坐标:x: 0-105, y: 0-68)
# 左路: y < 22.6; 右路: y > 45.4
left_wing = (df['start_y'] < 22.6)
right_wing = (df['start_y'] > 45.4)
wide_areas = left_wing | right_wing
# 定义“突破”事件
breakthrough_events = [
    'Dribble_Successful',  # 成功过人
    'Cross_Accurate',      # 成功传中
    'Shot_After_Dribble',  # 带球射门
    'Foul_Won_Wide'        # 边路造犯规
]
# 筛选:在边路且是突破事件的组合
df_breakthroughs = df[(df['event_type'].isin(breakthrough_events)) & wide_areas]
# 统计每个队在边路的突破次数
team_breakthrough_counts = df_breakthroughs.groupby('team').size().reset_index(name='突破次数')
# 统计传中成功率和过人成功率
team_cross_stats = df[df['event_type'] == 'Cross'].groupby('team').agg(
    传中总数 = ('event_id', 'count'),
    传中成功 = ('outcome', lambda x: (x == 'Accurate').sum())
).reset_index()
team_cross_stats['传中成功率'] = team_cross_stats['传中成功'] / team_cross_stats['传中总数']
# 条形图对比
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
# 左图:边路突破次数
axes[0].bar(team_breakthrough_counts['team'], team_breakthrough_counts['突破次数'], color=['#FF6347', '#4682B4'])
axes[0].set_title('边路总突破次数')
axes[0].set_ylabel('次数')
# 右图:传中成功率
axes[1].bar(team_cross_stats['team'], team_cross_stats['传中成功率'], color=['#FF6347', '#4682B4'])
axes[1].set_title('边路传中成功率')
axes[1].set_ylabel('成功率')
plt.tight_layout()
plt.show()

解读: 如果一队“边路总突破次数”高,但“传中成功率”低,说明他们可能只会“闷头带”,缺乏有效终结;反之亦然。


热力图可视化(Matplotlib + 散点图)

如果你有球员触球/活动坐标数据,可以直接画热力图,直观看到哪队更擅长在高危边路区域活动。

代码示例:基于坐标的边路活动密度

# 假设你有两队的坐标数据: df_teamA_events, df_teamB_events
# 过滤出边路区域的过人/传中事件
from scipy.stats import gaussian_kde
import matplotlib.pyplot as plt
def plot_wing_heatmap(df_team, team_name, ax):
    # 筛选边路 (y坐标 < 20 或 > 48)
    df_wide = df_team[(df_team['y'] < 20) | (df_team['y'] > 48)]
    # 只保留进攻端事件 (x > 50, 半场进攻)
    df_attack_wide = df_wide[df_wide['x'] > 50]
    if len(df_attack_wide) > 10:
        # 核密度估计
        xy = np.vstack([df_attack_wide['x'], df_attack_wide['y']])
        z = gaussian_kde(xy)(xy)
        ax.scatter(df_attack_wide['x'], df_attack_wide['y'], 
                   c=z, s=50, alpha=0.6, cmap='Reds')
        ax.set_title(f'{team_name} 边路进攻热区')
    else:
        ax.text(0.5, 0.5, '数据不足', ha='center')
fig, axes = plt.subplots(1, 2, figsize=(12, 6))
plot_wing_heatmap(df_teamA, '队A', axes[0])
plot_wing_heatmap(df_teamB, '队B', axes[1])
# 添加球场背景 (可选, 需要 matplotlib.patches)
# ...
plt.suptitle('两队边路突破空间对比')
plt.show()

如何选择方案?

你的数据类型 推荐方案 核心洞察
汇总统计表 (球员场均过人数等) 方案一 雷达图 综合对比各维度强弱项
逐事件流 (带坐标和结果) 方案二 条件聚合 精确统计有效突破次数和效率
原始坐标/轨迹数据 方案三 热力图 战术空间压迫感和核心区域

进阶建议:

  • 你可以加入每90分钟数据(per90)来消除出场时间差异。
  • 使用 Mplsoccer 库(专门画足球场地的Python库)能让图更加专业。
  • 如果对比的是总突破 vs 威胁突破,可以引入“突破后射门”、“突破后关键传球”等后续指标。

如果你能提供你具体的数据格式(列名和样本),我可以直接帮你写一段适配的代码。

上一篇根据Python案例,射门转化率哪队更高?

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

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