这个Python案例显示横传转移球次数?

wen python案例 1

本文目录导读:

这个Python案例显示横传转移球次数?

  1. 核心思路与Python实现框架
  2. 如果你的案例数据是“SoccerAction”格式(或某个具体代码)

要准确回答你的问题,我需要先澄清一下:“横传转移球次数”这个指标在标准的足球数据统计中并没有一个固定的、唯一的定义,它通常取决于数据提供商(如Opta、StatsBomb、Wyscout)或具体分析人员的自定义规则

最常见的定义是:传球方向与球场水平线(边线)的夹角较小(例如小于45度或30度),且传球距离较长(通常超过20-30米),目的是将球从球场一侧快速转移到另一侧,以改变进攻方向。

由于你没有提供具体的Python代码或数据集,我无法直接分析那个案例,但我可以给你一个通用的Python逻辑和代码框架,帮助你理解如何计算“横传转移球次数”,你可以根据这个框架修改,应用到你的具体数据中。


核心思路与Python实现框架

假设你有一个包含足球赛事事件数据的DataFrame(例如从StatsBomb或Wyscout导入),每一行是一次传球事件,包含以下关键字段:

  • team_id: 球队ID
  • player_name: 球员名
  • x, y: 传球起始坐标 (球场通常为 0-120 x 0-80)
  • end_x, end_y: 传球结束坐标
  • pass_type: 传球类型 (可选)
  • play_pattern: 比赛模式 (如常规进攻、角球等)

第一步:定义“横传转移球”

通常需要满足三个条件:

  1. 传球方向偏向横向:用 delta_xdelta_y 计算角度,判断是否接近水平。
  2. 传球距离较远:设置一个最小距离阈值(如25米)。
  3. 发生在中前场:排除后场倒脚(可选)。

第二步:编写Python函数

import pandas as pd
import numpy as np
def is_switch_of_play(row, angle_threshold=30, distance_threshold=25, field_length=105, field_width=68):
    """
    判断一次传球是否为横传转移球。
    假设球场坐标系:x为长度方向(0-105), y为宽度方向(0-68)
    """
    # 1. 计算传球距离 (米)
    dx = row['end_x'] - row['x']
    dy = row['end_y'] - row['y']
    distance = np.sqrt(dx**2 + dy**2)
    # 如果距离太短,不是转移球
    if distance < distance_threshold:
        return False
    # 2. 计算传球方向与水平线的夹角 (单位:度)
    # 水平线角度为0度(纯横传),垂直线为90度(纯直传)
    # 使用atan2: 角度相对于x轴 (横向)
    angle = np.abs(np.degrees(np.arctan2(dy, dx)))
    # 取锐角(0-90)
    if angle > 90:
        angle = 180 - angle
    # 如果角度小于阈值(即接近横传),认为是转移球
    # 有些定义会使用更严格的阈值,如 < 30度
    if angle > angle_threshold:
        return False
    # 3. (可选) 过滤掉后场倒脚,例如只考虑中前场
    # 假设起点在中线附近或靠近对方禁区
    if row['x'] < field_length * 0.3:  # 起点在自己半场太深
        return False
    return True
# 应用到DataFrame
df['is_switch'] = df.apply(is_switch_of_play, axis=1)
# 统计每场比赛/每支球队的横传转移次数
switch_counts = df[df['is_switch']].groupby(['match_id', 'team_name']).size().reset_index(name='switch_count')

第三步:改进与注意事项

  1. 球场坐标系映射

    • 不同的数据源坐标系不同,例如StatsBomb使用 (0,0)(120,80)(单位是码,需转为米)。
    • 有些数据源使用归一化坐标 (0,0)(1,1),你需要根据实际数据调整阈值。
    • 常见转换:假设球场长105米,宽68米,则:
      field_length_m = 105.0
      field_width_m = 68.0
      # 如果数据坐标是 0-120 (码)
      length_scale = field_length_m / 120.0
      width_scale = field_width_m / 80.0
      row['x'] = row['x'] * length_scale
      row['y'] = row['y'] * width_scale
  2. 更严格的“转移球”定义

    • 有些分析还要求:传球跨越了球场中线(即起点和终点分布在球场左右两侧的不同半区)。
    • 可以增加条件:
      # 起点在左侧,终点在右侧(或相反)
      center_y = field_width / 2.0
      if (row['y'] < center_y and row['end_y'] < center_y) or \
         (row['y'] > center_y and row['end_y'] > center_y):
          return False  # 没有跨越中轴线
  3. 可视化验证

    • mplsoccermatplotlib 画出这些传球,确认规则合理。
      from mplsoccer import Pitch
      pitch = Pitch(pitch_type='custom', pitch_length=105, pitch_width=68)
      # 筛选是转移球的传球
      switches = df[df['is_switch'] == True]
      # 绘制... (代码略)

如果你的案例数据是“SoccerAction”格式(或某个具体代码)

请提供:

  1. 你的数据集的列名(特别是坐标、比赛ID、球队ID)
  2. 你的数据集坐标系范围(例如x轴是0-100还是0-120)
  3. 你期望的横传定义(是否要求跨越半场?距离阈值?)

我可以根据你的具体字段,给出可直接运行的修改代码


“横传转移球次数”的计算公式是:

  1. 筛选传球距离 > 25米的事件
  2. 筛选传球方向与水平线夹角 < 30度的事件
  3. (可选) 筛选起点和终点位于球场不同侧(左右)的事件
  4. 按球队或球员groupby计数

上面的Python函数可以直接复制并调整参数,应用到你的案例中,如果你能分享你的数据样例(几行即可,注意脱敏),我可以帮你写出精确适配的代码。

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