这个实用脚本显示横传转移球次数?

wen 实用脚本 4

本文目录导读:

这个实用脚本显示横传转移球次数?

  1. 功能特点:
  2. 使用示例:
  3. 运行脚本:
  4. 输出示例:
  5. 调整参数:

我来帮你创建一个统计横传转移球次数的实用脚本,横传转移通常指球场中路的横向传球或大范围转移,我会用Python编写一个可分析的脚本。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
足球横传转移球统计脚本
统计比赛中横向传球/大范围转移球的次数
"""
import json
import re
from collections import defaultdict
class TransferPassAnalyzer:
    """横传转移球分析器"""
    def __init__(self):
        # 球场坐标范围(标准足球场105m x 68m)
        self.PITCH_LENGTH = 105.0
        self.PITCH_WIDTH = 68.0
        # 横向转移判定参数
        self.MIN_TRANSFER_DISTANCE = 25.0  # 最小转移距离(米)
        self.MAX_TRANSFER_ANGLE = 30.0     # 最大传球角度(与横线的夹角)
        # 统计结果
        self.stats = {
            'total_passes': 0,
            'transfer_passes': 0,
            'transfer_rate': 0.0,
            'players': defaultdict(lambda: {'total': 0, 'transfer': 0}),
            'areas': defaultdict(int)
        }
    def analyze_pass(self, x1, y1, x2, y2):
        """
        分析单次传球是否为横传转移
        参数:
        x1, y1: 传球起始坐标
        x2, y2: 传球结束坐标
        """
        # 计算传球距离
        distance = ((x2-x1)**2 + (y2-y1)**2) ** 0.5
        # 计算传球角度(相对于横向的夹角)
        # 横向传球角度小,纵向传球角度大
        if distance > 0:
            # 计算与横向(x方向)的夹角
            angle = abs(__import__('math').atan2(abs(y2-y1), abs(x2-x1)))
            angle_deg = __import__('math').degrees(angle)
        else:
            angle_deg = 90.0
        # 判断是否为横传转移
        is_transfer = (
            distance >= self.MIN_TRANSFER_DISTANCE and
            angle_deg <= self.MAX_TRANSFER_ANGLE
        )
        return is_transfer, distance, angle_deg
    def analyze_match(self, events):
        """
        分析整场比赛事件
        参数:
        events: 传球事件列表,每个事件包含:
                {'player': '球员名', 'x1': x, 'y1': y, 'x2': x, 'y2': y, 'team': '队伍'}
        """
        transfer_events = []
        for event in events:
            self.stats['total_passes'] += 1
            # 分析传球
            is_transfer, distance, angle = self.analyze_pass(
                event['x1'], event['y1'], event['x2'], event['y2']
            )
            # 更新球员统计
            player_name = event.get('player', 'unknown')
            team = event.get('team', 'unknown')
            self.stats['players'][f"{team}-{player_name}"]['total'] += 1
            if is_transfer:
                self.stats['transfer_passes'] += 1
                self.stats['players'][f"{team}-{player_name}"]['transfer'] += 1
                # 记录转移区域(前场/中场/后场)
                mid_x = (event['x1'] + event['x2']) / 2
                if mid_x < self.PITCH_LENGTH / 3:
                    area = '后场'
                elif mid_x < 2 * self.PITCH_LENGTH / 3:
                    area = '中场'
                else:
                    area = '前场'
                self.stats['areas'][area] += 1
                transfer_events.append({
                    **event,
                    'distance': distance,
                    'angle': angle,
                    'type': '横传转移'
                })
        # 计算转移率
        if self.stats['total_passes'] > 0:
            self.stats['transfer_rate'] = (
                self.stats['transfer_passes'] / self.stats['total_passes'] * 100
            )
        return transfer_events
    def print_report(self):
        """打印统计报告"""
        print("=" * 60)
        print("横传转移球统计报告")
        print("=" * 60)
        # 总体统计
        print(f"\n总体统计:")
        print(f"  总传球次数: {self.stats['total_passes']}")
        print(f"  横传转移次数: {self.stats['transfer_passes']}")
        print(f"  转移率: {self.stats['transfer_rate']:.2f}%")
        # 区域统计
        print(f"\n区域分布:")
        for area in ['后场', '中场', '前场']:
            count = self.stats['areas'].get(area, 0)
            percentage = (count / self.stats['transfer_passes'] * 100 
                         if self.stats['transfer_passes'] > 0 else 0)
            print(f"  {area}: {count}次 ({percentage:.1f}%)")
        # 球员统计
        print(f"\n球员统计(前10名):")
        sorted_players = sorted(
            self.stats['players'].items(),
            key=lambda x: x[1]['transfer'],
            reverse=True
        )[:10]
        print(f"  {'球员':<20} {'总传球':<10} {'横传转移':<10} {'转移率'}")
        print("  " + "-" * 55)
        for player, data in sorted_players:
            rate = (data['transfer'] / data['total'] * 100 
                   if data['total'] > 0 else 0)
            print(f"  {player:<20} {data['total']:<10} {data['transfer']:<10} {rate:.1f}%")
        print("=" * 60)
def load_events_from_file(filepath):
    """从JSON文件加载事件数据"""
    try:
        with open(filepath, 'r', encoding='utf-8') as f:
            return json.load(f)
    except FileNotFoundError:
        print(f"错误: 找不到文件 {filepath}")
        return []
    except json.JSONDecodeError:
        print(f"错误: 文件 {filepath} 不是有效的JSON格式")
        return []
def load_events_from_csv(filepath):
    """从CSV文件加载事件数据"""
    import csv
    events = []
    try:
        with open(filepath, 'r', encoding='utf-8') as f:
            reader = csv.DictReader(f)
            for row in reader:
                try:
                    event = {
                        'player': row.get('player', 'unknown'),
                        'team': row.get('team', 'unknown'),
                        'x1': float(row.get('x1', 0)),
                        'y1': float(row.get('y1', 0)),
                        'x2': float(row.get('x2', 0)),
                        'y2': float(row.get('y2', 0))
                    }
                    events.append(event)
                except ValueError as e:
                    print(f"警告: 跳过无效行 {row}: {e}")
    except FileNotFoundError:
        print(f"错误: 找不到文件 {filepath}")
    return events
def generate_sample_data():
    """生成示例数据用于测试"""
    import random
    events = []
    players = [
        ('张伟', '主队'), ('李强', '主队'), ('王芳', '主队'),
        ('赵磊', '主队'), ('刘洋', '主队'), ('陈杰', '主队'),
        ('杨光', '客队'), ('周明', '客队'), ('吴昊', '客队'),
        ('郑浩', '客队'), ('孙鹏', '客队'), ('马超', '客队')
    ]
    # 生成100个传球事件
    for _ in range(100):
        player, team = random.choice(players)
        # 随机位置
        x1 = random.uniform(0, 105)
        y1 = random.uniform(0, 68)
        # 传球方向:随机偏向横向或纵向
        if random.random() < 0.3:  # 30%概率横向转移
            x2 = x1 + random.uniform(-30, 30)
            y2 = y1 + random.uniform(-5, 5)
        else:  # 其他传球
            x2 = x1 + random.uniform(-20, 20)
            y2 = y1 + random.uniform(-20, 20)
        # 确保在球场范围内
        x2 = max(0, min(105, x2))
        y2 = max(0, min(68, y2))
        events.append({
            'player': player,
            'team': team,
            'x1': x1,
            'y1': y1,
            'x2': x2,
            'y2': y2
        })
    return events
def main():
    """主函数"""
    analyzer = TransferPassAnalyzer()
    # 选择数据来源
    print("选择数据输入方式:")
    print("1. 使用示例数据")
    print("2. 从JSON文件加载")
    print("3. 从CSV文件加载")
    choice = input("请输入选项 (1-3): ").strip()
    if choice == '1':
        # 生成示例数据
        events = generate_sample_data()
        print(f"使用示例数据 ({len(events)}次传球)")
    elif choice == '2':
        filepath = input("请输入JSON文件路径: ").strip()
        events = load_events_from_file(filepath)
        if not events:
            print("未能加载数据,退出")
            return
    elif choice == '3':
        filepath = input("请输入CSV文件路径: ").strip()
        events = load_events_from_csv(filepath)
        if not events:
            print("未能加载数据,退出")
            return
    else:
        print("无效选项")
        return
    # 分析数据
    transfer_events = analyzer.analyze_match(events)
    # 输出报告
    analyzer.print_report()
    # 保存转移球详情
    if transfer_events:
        save_choice = input("\n是否保存转移球详细数据? (y/n): ").strip().lower()
        if save_choice == 'y':
            filename = 'transfer_passes.json'
            with open(filename, 'w', encoding='utf-8') as f:
                json.dump(transfer_events, f, ensure_ascii=False, indent=2)
            print(f"详细数据已保存至 {filename}")
if __name__ == "__main__":
    main()

这个脚本的使用方法:

功能特点:

  1. 核心功能

    • 统计横传转移球的次数
    • 计算转移球占总传球的比例
    • 按区域(前场/中场/后场)统计
    • 按球员统计个人转移球数据
  2. 判定标准

    • 传球距离 ≥ 25米
    • 传球角度与横线夹角 ≤ 30度
  3. 数据输入方式

    • 示例数据(用于测试)
    • JSON文件
    • CSV文件

使用示例:

# 数据格式示例
pass_events = [
    {
        "player": "梅西",
        "team": "巴萨",
        "x1": 45.0,  # 出发x坐标
        "y1": 20.0,  # 出发y坐标
        "x2": 70.0,  # 到达x坐标
        "y2": 22.0   # 到达y坐标
    },
    # ... 更多传球事件
]

运行脚本:

python3 transfer_pass_analyzer.py

输出示例:

============================================================
横传转移球统计报告
============================================================
总体统计:
  总传球次数: 100
  横传转移次数: 34
  转移率: 34.00%
区域分布:
  后场: 12次 (35.3%)
  中场: 15次 (44.1%)
  前场: 7次 (20.6%)
球员统计(前10名):
  球员                 总传球    横传转移    转移率
  -------------------------------------------------------
  主队-王芳            12        5          41.7%
  客队-杨光            10        4          40.0%
  ...

调整参数:

你可以根据需要调整判定标准:

  • MIN_TRANSFER_DISTANCE:最小转移距离
  • MAX_TRANSFER_ANGLE:最大允许角度

如果需要支持其他格式或更复杂的数据分析,请告诉我!

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