python案例统计高球传中争顶成功率?

wen python案例 1

本文目录导读:

python案例统计高球传中争顶成功率?

  1. 引言:为什么高球传中争顶成功率是足球数据分析的黄金指标?
  2. 数据准备:从哪里获取传中与争顶事件数据?
  3. Python案例实战:一步步统计传中争顶成功率
  4. 关键代码解析:事件定义、匹配逻辑与可视化
  5. 常见问题问答(FAQ)
  6. SEO优化建议:如何让这篇文章在必应和谷歌排名靠前?
  7. 总结与进阶方向

Python实战案例:统计足球比赛高球传中与争顶成功率(附完整代码与SEO优化指南)**


目录导读

  1. 引言:为什么高球传中争顶成功率是足球数据分析的黄金指标?
  2. 数据准备:从哪里获取传中与争顶事件数据?
  3. Python案例实战:一步步统计传中争顶成功率
  4. 关键代码解析:事件定义、匹配逻辑与可视化
  5. 常见问题问答(FAQ)
  6. SEO优化建议:如何让这篇文章在必应和谷歌排名靠前?
  7. 总结与进阶方向

引言:为什么高球传中争顶成功率是足球数据分析的黄金指标?

在现代足球战术分析中,高球传中与争顶成功率是衡量球队边路进攻效率、中锋支点能力以及防守高空球能力的关键数据,无论是英超、西甲还是世界杯,教练团队都会关注:一次传中后,进攻方有多少次成功争到第一落点?这直接决定了二次进攻的威胁程度。

传统人工统计耗时且易错,借助Python,我们可以批量处理事件数据(如StatsBomb、Opta或Wyscout格式),自动计算传中次数、争顶次数以及成功率,本文将通过一个完整案例,带你从零实现这一统计过程,并给出可复用的代码框架。

搜索引擎中已有不少关于“传中成功率”的文章,但多数停留在Excel或简单描述,本文将去伪原创,融合实战代码与业务逻辑,确保你在必应和谷歌上获得更好的排名。


数据准备:从哪里获取传中与争顶事件数据?

常见公开数据源包括:

  • StatsBomb Open Data:免费提供世界杯、女足等赛事的事件数据(JSON格式)。
  • FBref:可爬取传中与争顶统计,但需遵守robots协议。
  • Wyscout:部分公开数据集,包含“Cross”和“Aerial Duel”标签。
  • 自建标注:使用Python+OpenCV从视频中提取,但成本较高。

本文以StatsBomb格式为例,其事件类型中:

  • Pass 事件中 pass.cross == True 表示传中。
  • Duel 事件中 duel.type.name == "Aerial Lost""Aerial Won" 表示争顶。
  • 注意:一次传中后可能紧接着一次争顶,也可能被解围或直接出界。

我们需要将传中事件与随后的争顶事件在时间窗口内匹配,通常设定:传中发生后5秒内,同一半场内发生的第一次争顶视为该传中的结果。


Python案例实战:一步步统计传中争顶成功率

1 加载与清洗数据

import json
import pandas as pd
from datetime import timedelta
# 读取StatsBomb事件JSON
with open('events.json', 'r', encoding='utf-8') as f:
    events = json.load(f)
df = pd.json_normalize(events)
df['timestamp'] = pd.to_datetime(df['timestamp'], format='%H:%M:%S.%f').dt.time
df['minute'] = df['minute'].astype(int)
df['second'] = df['second'].astype(int)
df['total_seconds'] = df['minute'] * 60 + df['second']

2 筛选传中事件

crosses = df[
    (df['type.name'] == 'Pass') &
    (df['pass.cross'] == True)
].copy()
crosses = crosses[['id', 'index', 'total_seconds', 'player.name', 'team.name', 'location']]
crosses.columns = ['cross_id', 'cross_index', 'cross_time', 'crosser', 'cross_team', 'cross_location']

3 筛选争顶事件

duels = df[
    (df['type.name'] == 'Duel') &
    (df['duel.type.name'].isin(['Aerial Lost', 'Aerial Won']))
].copy()
duels = duels[['index', 'total_seconds', 'player.name', 'team.name', 'duel.type.name', 'location']]
duels.columns = ['duel_index', 'duel_time', 'dueler', 'duel_team', 'duel_result', 'duel_location']

4 匹配传中与争顶(5秒窗口)

matched = []
for _, cross in crosses.iterrows():
    # 找同一半场内、传中后5秒内的第一次争顶
    candidates = duels[
        (duels['duel_time'] > cross['cross_time']) &
        (duels['duel_time'] <= cross['cross_time'] + 5)
    ]
    if not candidates.empty:
        first_duel = candidates.sort_values('duel_time').iloc[0]
        matched.append({
            'cross_id': cross['cross_id'],
            'crosser': cross['crosser'],
            'cross_team': cross['cross_team'],
            'duel_result': first_duel['duel_result'],
            'duel_team': first_duel['duel_team'],
            'dueler': first_duel['dueler']
        })
matched_df = pd.DataFrame(matched)

5 计算成功率

# 进攻方争顶成功:争顶球队 == 传中球队 且 结果为 Aerial Won
matched_df['attack_win'] = (
    (matched_df['duel_team'] == matched_df['cross_team']) &
    (matched_df['duel_result'] == 'Aerial Won')
)
total_crosses = len(crosses)
crosses_with_duel = len(matched_df)
successful_attacks = matched_df['attack_win'].sum()
print(f"总传中次数: {total_crosses}")
print(f"有争顶的传中次数: {crosses_with_duel}")
print(f"进攻方争顶成功次数: {successful_attacks}")
print(f"传中争顶成功率: {successful_attacks / crosses_with_duel:.2%}")

6 可视化结果

import matplotlib.pyplot as plt
labels = ['成功争顶', '失败争顶']
sizes = [successful_attacks, crosses_with_duel - successful_attacks]
plt.pie(sizes, labels=labels, autopct='%1.1f%%')'高球传中后进攻方争顶成功率')
plt.show()

关键代码解析:事件定义、匹配逻辑与可视化

  • 事件定义:不同数据商对“传中”定义不同,StatsBomb中pass.cross为True即传中,包括角球、运动战传中,争顶仅考虑Aerial类型,排除地面对抗。
  • 匹配逻辑:5秒窗口是经验值,若传中后发生多次争顶,只取第一次,因为第一次争顶直接决定第一落点,若传中直接出界或门将接住,则无争顶,不计入成功率分母(但可单独统计“传中形成争顶率”)。
  • 可视化:饼图展示成功率,也可用条形图对比不同球员或球队。

常见问题问答(FAQ)

Q1:为什么我统计的成功率与Opta数据不一致? A:定义差异,Opta可能将传中后二次争顶也算入,或使用不同时间窗口,建议统一采用“第一次争顶”原则。

Q2:传中后没有争顶,是否算失败? A:通常不算,成功率分母应为“有争顶的传中次数”,但可另算“传中形成争顶率”=有争顶传中/总传中。

Q3:如何区分进攻方和防守方争顶成功? A:比较争顶球队与传中球队是否相同,相同且结果为Aerial Won,即进攻方成功。

Q4:可以统计单个球员的传中争顶成功率吗? A:可以,在crosses中按crosser分组,再匹配争顶即可。

Q5:数据量很大时如何加速? A:使用pandas.merge_asof按时间排序后近似匹配,避免循环。


SEO优化建议:如何让这篇文章在必应和谷歌排名靠前?

包含核心关键词**:“Python案例统计高球传中争顶成功率”已覆盖。

  • 目录导读:提升用户体验,增加停留时间。
  • 问答结构:符合Google Featured Snippet抓取习惯。
  • 代码可复制:技术文章外链和引用率高。
  • 内链与外链:引用StatsBomb官方文档、知名足球分析博客。
  • 移动端适配:代码块横向滚动,避免溢出。
  • 元描述:控制在155字符内,包含“Python”、“传中争顶”、“成功率”、“案例”。
  • URL:使用短横线分隔关键词,如/python-cross-aerial-duel-success-rate
  • 图片ALT:饼图添加描述“高球传中争顶成功率饼图”。

总结与进阶方向

本文通过Python完整演示了从事件数据中统计高球传中争顶成功率的方法,核心步骤:筛选传中→筛选争顶→时间窗口匹配→计算成功率→可视化,你可将此框架扩展至:

  • 按比赛阶段(上半场/下半场)分析
  • 按传球区域(左路/右路)对比
  • 结合xG(预期进球)评估传中质量
  • 使用Plotly制作交互式仪表盘

掌握这一技能,你不仅能输出专业足球分析报告,还能在数据科学面试中展示实战能力,立即用你手头的比赛数据跑一遍吧!

上一篇python案例认为这次直塞球穿透力如何?

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

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