python案例统计禁区内射门次数对比?

wen python案例 2

Python案例统计禁区内射门次数对比:从数据采集到可视化分析的完整实战

目录导读


为什么禁区内射门次数值得单独统计?

在足球数据分析领域,射门位置是衡量进攻质量的关键指标之一,禁区内的射门由于距离球门更近、角度更佳,其进球转化率通常远高于禁区外远射,据统计,顶级联赛中禁区内射门的平均转化率约为12%—15%,而禁区外射门往往只有3%—5%,单独统计禁区内射门次数,能够帮助教练团队、数据分析师和球迷更准确地评估一支球队的进攻效率与战术倾向。

python案例统计禁区内射门次数对比?

传统的技术统计往往只记录“总射门数”,这会掩盖很多问题,一支球队可能全场射门20次,但其中15次来自禁区外低质量的远射;另一支球队只射门10次,却有8次发生在禁区内,两者的进攻威胁显然不可同日而语,用Python对禁区内射门次数进行统计与对比,正是把这种“质量差异”量化出来的有效手段。

本文将通过一个完整的Python案例,演示如何从原始事件数据中筛选禁区内射门、按球队或球员分组统计、并进行横向对比与可视化,最终形成一份可复用的分析流程。


数据准备:从哪里获取射门数据

要进行禁区内射门统计,首先需要带有射门坐标的事件数据,常见的数据来源包括:

  1. StatsBomb开放数据:提供部分赛事(如世界杯、女足欧洲杯)的详细事件数据,字段包含射门位置坐标、是否在禁区内等,非常适合练手。
  2. FBref:提供球队与球员的射门统计,可导出CSV,但粒度较粗。
  3. Understat:提供射门坐标数据(xG模型),可抓取每脚射门的位置信息。
  4. 自建数据集:如果你有比赛录像标注数据,也可以整理成CSV。

本文以一份结构化的CSV数据为例,假设字段包括:match_id、team、player、shot_x、shot_y、is_box(是否禁区内)、is_goal,其中is_box可以直接使用,也可以根据坐标自行判断——通常以球场长度方向坐标判断射门点是否落在禁区矩形范围内。

需要提醒的是,不同数据源的坐标系定义不同(有的以米为单位,有的归一化到0—100或0—120),在判断“是否禁区内”之前,务必先确认坐标体系,避免统计口径出错,这是很多初学者容易踩的坑。


核心案例:用Python统计禁区内射门次数

代码部分,我们使用pandas完成数据读取、清洗与分组统计。

import pandas as pd
# 1. 读取数据
df = pd.read_csv("shots.csv")
# 2. 基础清洗:去除缺失坐标或队伍信息的记录
df = df.dropna(subset=["team", "shot_x", "shot_y"])
# 3. 若数据中没有 is_box 字段,可根据坐标判断
# 假设球场长120、宽80,禁区为靠近球门一侧长18、宽44的区域
def in_box(row):
    if "is_box" in row and pd.notna(row["is_box"]):
        return bool(row["is_box"])
    return row["shot_x"] >= 102 and 18 <= row["shot_y"] <= 62
df["in_box"] = df.apply(in_box, axis=1)
# 4. 按球队统计禁区内、外射门次数
pivot = df.groupby(["team", "in_box"]).size().unstack(fill_value=0)
pivot.columns = ["禁区外射门", "禁区内射门"]
pivot["总射门"] = pivot["禁区内射门"] + pivot["禁区外射门"]
pivot["禁区内占比"] = (pivot["禁区内射门"] / pivot["总射门"] * 100).round(1)
print(pivot.sort_values("禁区内射门", ascending=False))

这段代码的核心逻辑分三步:清洗、判定、分组。groupby配合unstack可以一次性得到每支球队在禁区内外的射门分布,随后计算占比字段,便于横向比较,若你想按球员统计,只需把groupby的键换成player即可。

在实际项目中,还建议增加去重逻辑(避免同一事件重复计入)和异常值过滤(如坐标越界),保证统计结果的可靠性。


对比分析:多支球队/多名球员的禁区内外射门差异

得到基础统计后,对比分析才是价值所在,我们可以从三个维度展开:

第一,总量对比。 比较各队禁区内射门次数绝对值,识别进攻火力最强的球队,但要注意,绝对次数受比赛场次影响,跨联赛对比时应换算为场均数据。

第二,结构对比。 用“禁区内射门占比”衡量进攻质量,占比高的球队更倾向于渗透禁区,占比低的球队可能依赖远射,将占比与总射门数结合,可以绘制散点图,把球队分成“高质量高产量”“高质量低产量”等象限。

第三,效率对比。 进一步引入进球数,计算禁区内射门的转化率,判断哪支球队把握机会能力更强,次数多不等于效率高,二者的对比往往能揭示战术执行力的差异。

可以这样计算场均与转化率:

matches = df.groupby("team")["match_id"].nunique()
pivot["场均禁区内射门"] = (pivot["禁区内射门"] / matches).round(2)
goals = df[df["is_goal"] == 1].groupby("team").size()
pivot["禁区内进球"] = goals.reindex(pivot.index).fillna(0)
pivot["禁区内转化率"] = (pivot["禁区内进球"] / pivot["禁区内射门"] * 100).round(1)

通过这套组合指标,对比就不仅仅停留在“谁射得多”,而是深入到“谁射得准、射得值”。


可视化呈现:让对比结果一目了然

数据表格适合细看,图形则适合快速传达结论,推荐两种图:

  1. 堆叠柱状图:展示每支球队禁区内与禁区外射门的构成,直观看出结构差异。
  2. 散点图:横轴为禁区内射门占比,纵轴为场均禁区内射门次数,气泡大小表示转化率,一图呈现多维对比。
import matplotlib.pyplot as plt
pivot[["禁区内射门", "禁区外射门"]].plot(kind="bar", stacked=True, figsize=(10, 6))"各队禁区内 vs 禁区外射门次数对比")
plt.ylabel("射门次数")
plt.tight_layout()
plt.show()

使用matplotlib或seaborn即可快速出图,若面向网页展示,可改用plotly生成交互图表,鼠标悬停查看具体数值,体验更佳,可视化时注意配色区分禁区内外,并在标题中直接点明对比主题,方便读者理解。


常见问题与优化建议

  • 坐标口径不统一:不同数据源坐标系差异大,务必先统一再判断禁区。
  • 样本量过小:单场比赛的射门次数波动大,建议至少累计多场再对比。
  • 忽略比赛情境:领先方可能减少进攻,落后方可能狂攻,对比时应结合比分状态分层。
  • 重复事件:部分数据源会记录被挡出后补射,注意去重规则。

优化方向包括:引入xG(预期进球)替代简单计数、按时间段切分统计、结合传球网络分析禁区渗透路径等,让分析更具深度。


问答环节

问:没有现成的is_box字段怎么办? 答:根据坐标自行判断,先确认球场坐标系(长度方向范围),再设定禁区矩形阈值,用条件筛选即可,本文第三节已给出示例函数。

问:禁区内射门次数越多,是否代表进攻越强? 答:不完全等价,次数反映产量,还需结合转化率与xG衡量质量,高次数低转化可能意味着把握机会能力不足。

问:如何按球员而非球队统计? 答:把groupby的键从team改为player,其余逻辑不变,并可增加出场时间字段换算为每90分钟数据。

问:数据量很大时性能如何优化? 答:优先使用向量化操作替代apply,将坐标判断改写为布尔索引,必要时用category类型降低内存占用。


本文围绕“Python案例统计禁区内射门次数对比”这一主题,完整走过了数据准备、清洗判定、分组统计、多维对比与可视化呈现的流程,核心要点有三:一是明确禁区判定口径,保证统计一致;二是用pandas分组聚合高效产出对比表;三是结合占比、场均与转化率等多维指标,避免单一数字误导结论,掌握这套方法后,你可以把它迁移到任意赛事数据上,快速生成有价值的进攻质量对比报告。

上一篇根据python案例,客队客场表现如何评估?

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

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

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