本文目录导读:

要为足球比赛分析显示“横传转移球”次数,我们需要先明确一个技术统计的定义:
横传转移球(Switch of Play / Square Pass):通常指球权在球场宽度上的大范围转移(通常是从一侧边路转移到另一侧边路),目的是改变进攻方向,但也有很多分析视频将“所有横向传球”都统计在内。
由于你没有指定是哪款足球游戏(如 FIFA/FC、实况足球)或哪款分析软件(如 DataVolley、Sportscode),我将为你提供一个通用的 Python 示例脚本。
这个脚本的思路是:基于球员传球的坐标数据,计算每次传球的角度和距离,并判断是否为“横传转移”。
脚本逻辑(核心算法)
- 输入数据:假设你有一个包含传球数据的 CSV 文件(包含传球起点
X1, Y1和终点X2, Y2坐标)。 - 判断标准(通常的标准):
- 角度:传球方向与球场长边(X轴)的夹角大于 45 度(即主要是横向移动)。
- 距离:传球距离超过一定阈值(25 米),排除短距离横传配合。
- 输出:打印横传转移球的次数。
通用 Python 脚本
import csv
import math
def is_switch_of_play(pass_data, angle_threshold=45, distance_threshold=25):
"""
判断单次传球是否为“横传转移球”。
参数:
- pass_data: 包含 x1, y1, x2, y2 的字典或列表
- angle_threshold: 与水平线的夹角阈值(度),默认45度
- distance_threshold: 最小传球距离(米/单位),默认25单位
返回:
- bool: 是否为横传转移球
"""
# 计算坐标差值(假设球场坐标系)
dx = pass_data['x2'] - pass_data['x1']
dy = abs(pass_data['y2'] - pass_data['y1']) # 横向移动距离(宽)
# 计算传球绝对距离
distance = math.sqrt(dx**2 + dy**2)
# 计算与 X 轴(纵向推进方向)的夹角
# 防呆处理:dx 为 0,角度为 90度(纯横向)
if dx == 0:
angle = 90.0
else:
# 计算角度(相对于垂直方向)
# 这里使用 atan2(dy, dx),并取绝对值
angle = abs(math.degrees(math.atan2(dy, dx)))
# 判断逻辑:
# 1. 角度 > 阈值:说明是横向传球(而非向前传球)
# 2. 距离 > 阈值:说明是大范围转移(而非普通短传)
if angle >= angle_threshold and distance >= distance_threshold:
return True
else:
return False
def analyze_passes_from_csv(filepath):
"""
从 CSV 文件读取传球数据,统计横传转移球次数。
CSV 格式要求:
- 必须有列名:x1, y1, x2, y2
- 坐标单位可以是米或任意单位(如果球场长度为100)
"""
switch_count = 0
total_passes = 0
try:
with open(filepath, mode='r', encoding='utf-8') as file:
reader = csv.DictReader(file)
for row in reader:
total_passes += 1
# 转换为浮点数
pass_data = {
'x1': float(row['x1']),
'y1': float(row['y1']),
'x2': float(row['x2']),
'y2': float(row['y2'])
}
if is_switch_of_play(pass_data):
switch_count += 1
# 打印这条有效的转移球
print(f"[转移球] 传球 #{total_passes}: 从 ({pass_data['x1']:.1f}, {pass_data['y1']:.1f}) 到 ({pass_data['x2']:.1f}, {pass_data['y2']:.1f})")
print("\n" + "="*40)
print(f"总传球次数: {total_passes}")
print(f"横传转移球次数: {switch_count}")
print(f"转移球占比: {switch_count/total_passes:.2%}" if total_passes > 0 else "无数据")
except FileNotFoundError:
print(f"错误: 文件 {filepath} 未找到。")
except KeyError as e:
print(f"错误: CSV 文件中缺少必要的列 {e}")
except Exception as e:
print(f"发生未知错误: {e}")
# --- 使用示例 ---
# 1. 创建模拟数据(如果你想测试,可以复制以下代码到文件里运行)
if __name__ == "__main__":
# 创建一个测试 CSV 文件(示例数据)
sample_data = """x1,y1,x2,y2\n10,10,15,12\n10,10,80,12\n20,20,25,22\n5,40,90,45\n50,50,52,55"""
test_file = "sample_passes.csv"
with open(test_file, "w") as f:
f.write(sample_data)
print("--- 正在分析示例数据 ---")
print("数据说明:第二组 (10,10)->(80,12),第四组 (5,40)->(90,45) 应该是转移球")
print("\n分析结果:")
analyze_passes_from_csv(test_file)
# 删除临时文件
import os
os.remove(test_file)
如何调整以适配你的具体需求
如果你有特定的数据源,请参考以下调整方式:
-
如果你使用的是“坐标轴相反”的数据(如
0-100为 X 轴代表宽度,0-68为 Y 轴代表高度):- 修改
dx和dy的定义,确保dy代表球场的长边移动距离,dx代表宽度。 - 修改角度计算的基准轴。
- 修改
-
如果你使用的是视频分析软件(如 Sportscode):
- 需要将该软件导出的
.xml或有特定格式的数据进行解析,提取出坐标字段即可。
- 需要将该软件导出的
-
如果你只需要“某一侧”的转移(比如左后卫转移到右边锋):
可以添加代码,检查传球起点的Y坐标和传球终点的Y坐标方向。
预测(可能是你们期望的另一种情况)
如果你想要的是一个能直接看的 Web 界面/实况显示(比如在 Obsidian 或 Grafana 中实时显示),那通常是调用 API,如果你能告诉我你具体的数据来源或想运行的平台(Python/Jupyter/Excel/网页),我可以为你定制一个更精准的“实用脚本”。