Python案例统计撞墙式配合完成了几次?

wen python案例 3

本文目录导读:

Python案例统计撞墙式配合完成了几次?

  1. 方案1:基于比赛事件数据的统计
  2. 方案2:基于比赛数据文件的统计分析
  3. 方案3:实时视频分析(进阶版本)

我来帮你创建一个Python案例来统计"撞墙式配合"(也就是二过一配合)的次数,这个统计通常用于足球比赛分析。

方案1:基于比赛事件数据的统计

def count_wall_pass_events(events):
    """
    统计撞墙式配合(二过一配合)的次数
    撞墙式配合的判定条件:
    1. 两个球员之间的连续传球
    2. 传球过程中有防守球员被过掉
    3. 传球和接球发生的区域变化
    参数:
    events: 比赛事件列表,每个事件包含时间、球员、类型、位置等信息
    返回:
    wall_pass_count: 撞墙式配合的次数
    """
    wall_pass_count = 0
    potential_wall_passes = []  # 存储潜在的配合事件
    # 遍历所有传球事件
    for i in range(len(events) - 2):
        event1 = events[i]
        event2 = events[i+1]
        event3 = events[i+2]
        # 检查是否是连续的传球事件(球员A传给B,B马上传回给A)
        if (event1['type'] == 'pass' and 
            event2['type'] == 'pass' and 
            event3['type'] == 'pass'):
            # 检查是否是撞墙式配合
            if (event1['to'] == event2['from'] and  # A传给B
                event2['to'] == event1['from'] and  # B传回给A
                abs(event1['timestamp'] - event2['timestamp']) < 3.0):  # 3秒内完成
                # 检查是否有防守球员在附近
                if has_defender_nearby(event1, event2):
                    wall_pass_count += 1
                    potential_wall_passes.append({
                        'player_a': event1['from'],
                        'player_b': event2['from'],
                        'timestamp': event1['timestamp'],
                        'area': get_area(event1, event2)
                    })
    return wall_pass_count, potential_wall_passes
def has_defender_nearby(event1, event2, threshold=5.0):
    """
    检查传球过程中是否有防守球员在附近
    threshold: 防守球员距离的阈值(米)
    """
    # 这里需要根据实际数据判断
    # 可以检查传球角度、防守球员位置等
    return True  # 简化处理
def get_area(event1, event2):
    """
    确定配合发生的区域
    """
    # 根据球场位置划分区域
    avg_x = (event1['x'] + event2['x']) / 2
    avg_y = (event1['y'] + event2['y']) / 2
    if avg_x < 34:
        return 'defensive_third'
    elif avg_x < 68:
        return 'middle_third'
    else:
        return 'offensive_third'
# 示例数据
sample_events = [
    {'timestamp': 10.5, 'type': 'pass', 'from': 'PlayerA', 'to': 'PlayerB', 'x': 50, 'y': 30},
    {'timestamp': 11.2, 'type': 'pass', 'from': 'PlayerB', 'to': 'PlayerA', 'x': 55, 'y': 35},
    {'timestamp': 11.8, 'type': 'pass', 'from': 'PlayerA', 'to': 'PlayerC', 'x': 60, 'y': 40},
    {'timestamp': 13.0, 'type': 'pass', 'from': 'PlayerC', 'to': 'PlayerB', 'x': 65, 'y': 25},
    {'timestamp': 15.5, 'type': 'pass', 'from': 'PlayerD', 'to': 'PlayerE', 'x': 70, 'y': 30},
    {'timestamp': 16.2, 'type': 'pass', 'from': 'PlayerE', 'to': 'PlayerD', 'x': 75, 'y': 35},
]
# 执行统计
count, details = count_wall_pass_events(sample_events)
print(f"撞墙式配合完成次数: {count}")
print(f"详细记录: {details}")

方案2:基于比赛数据文件的统计分析

import pandas as pd
from datetime import datetime
class WallPassAnalyzer:
    def __init__(self):
        self.wall_passes = []
        self.combinations = {}  # 统计不同球员组合的配合次数
    def analyze_match(self, match_data):
        """
        分析整场比赛的撞墙式配合
        参数:
        match_data: DataFrame,包含所有传球事件
        返回:
        total_wall_passes: 总次数
        detailed_stats: 详细统计信息
        """
        # 预处理数据
        match_data = match_data.sort_values('time')
        match_data['pass_pair'] = match_data.apply(
            lambda x: tuple(sorted([x['passer'], x['receiver']])), axis=1
        )
        # 找出潜在的配合事件
        wall_pass_events = []
        for idx in range(len(match_data) - 1):
            current_pass = match_data.iloc[idx]
            next_pass = match_data.iloc[idx + 1]
            # 检查时间间隔(通常撞墙式配合在1-3秒内完成)
            time_diff = (next_pass['time'] - current_pass['time']).total_seconds()
            if time_diff > 3.0:  # 时间间隔太长,不是撞墙式配合
                continue
            # 检查是否是来回传球
            if (current_pass['receiver'] == next_pass['passer'] and 
                current_pass['passer'] == next_pass['receiver']):
                # 计算区域变化
                area_change = self.calculate_area_change(
                    current_pass['x'], current_pass['y'],
                    next_pass['x'], next_pass['y']
                )
                # 检查是否向前推进
                if area_change > 0:  # 向前推进
                    wall_pass_events.append({
                        'player1': current_pass['passer'],
                        'player2': current_pass['receiver'],
                        'time': current_pass['time'],
                        'area': self.get_zone(current_pass['x'], current_pass['y']),
                        'effectiveness': self.evaluate_effectiveness(
                            current_pass, next_pass
                        ),
                        'distance': self.calculate_distance(
                            current_pass['x'], current_pass['y'],
                            next_pass['x'], next_pass['y']
                        )
                    })
        # 更新统计
        self.wall_passes.extend(wall_pass_events)
        # 统计组合次数
        for wp in wall_pass_events:
            combo = tuple(sorted([wp['player1'], wp['player2']]))
            if combo in self.combinations:
                self.combinations[combo] += 1
            else:
                self.combinations[combo] = 1
        return len(wall_pass_events), wall_pass_events
    def calculate_area_change(self, x1, y1, x2, y2):
        """
        计算区域变化,正值表示向前推进
        """
        return x2 - x1
    def get_zone(self, x, y):
        """
        根据坐标系判断球场区域
        """
        # 假设球场长度为105米,划分为3个区域
        if x < 35:
            return "防守三区"
        elif x < 70:
            return "中场"
        else:
            return "进攻三区"
    def evaluate_effectiveness(self, pass1, pass2):
        """
        评估配合效果
        返回:
        'successful', 'neutral', 'failed'
        """
        # 根据后续事件判断配合效果
        return 'successful'
    def calculate_distance(self, x1, y1, x2, y2):
        """
        计算传球距离
        """
        return ((x2 - x1)**2 + (y2 - y1)**2)**0.5
    def generate_report(self, match_name):
        """
        生成统计报告
        """
        report = f"\n{'='*50}\n"
        report += f"比赛名称: {match_name}\n"
        report += f"总计撞墙式配合: {len(self.wall_passes)} 次\n"
        report += f"{'='*50}\n\n"
        # 按组合统计
        report += "球员组合统计:\n"
        for combo, count in sorted(self.combinations.items(), key=lambda x: -x[1]):
            report += f"  {combo[0]} + {combo[1]}: {count} 次\n"
        # 按区域统计
        zone_stats = {}
        for wp in self.wall_passes:
            zone = wp['area']
            zone_stats[zone] = zone_stats.get(zone, 0) + 1
        report += "\n区域分布:\n"
        for zone, count in zone_stats.items():
            report += f"  {zone}: {count} 次\n"
        # 计算成功率
        successful = sum(1 for wp in self.wall_passes if wp['effectiveness'] == 'successful')
        if self.wall_passes:
            success_rate = (successful / len(self.wall_passes)) * 100
            report += f"\n成功率: {success_rate:.1f}%\n"
        report += f"{'='*50}\n"
        return report
# 使用示例
if __name__ == "__main__":
    # 创建示例数据
    data = {
        'time': [
            datetime(2024, 1, 1, 15, 0, 0),
            datetime(2024, 1, 1, 15, 0, 2),
            datetime(2024, 1, 1, 15, 0, 5),
            datetime(2024, 1, 1, 15, 0, 7),
        ],
        'passer': ['PlayerA', 'PlayerB', 'PlayerA', 'PlayerC'],
        'receiver': ['PlayerB', 'PlayerA', 'PlayerC', 'PlayerB'],
        'x': [50, 55, 60, 65],
        'y': [30, 35, 40, 25]
    }
    match_df = pd.DataFrame(data)
    # 进行分析
    analyzer = WallPassAnalyzer()
    count, details = analyzer.analyze_match(match_df)
    print(f"分析完成!撞墙式配合次数: {count}")
    print(analyzer.generate_report("示例比赛"))

方案3:实时视频分析(进阶版本)

import cv2
import numpy as np
class RealtimeWallPassDetector:
    def __init__(self):
        self.player_positions = {}
        self.passing_events = []
        self.wall_pass_count = 0
    def process_frame(self, frame, player_detections):
        """
        处理视频帧,实时检测撞墙式配合
        参数:
        frame: 当前视频帧
        player_detections: 该帧检测到的球员位置
        """
        # 更新球员位置
        for player_id, position in player_detections.items():
            if player_id in self.player_positions:
                # 计算移动速度
                last_pos = self.player_positions[player_id]['position']
                speed = self.calculate_speed(last_pos, position)
                self.player_positions[player_id]['speed'] = speed
                self.player_positions[player_id]['position'] = position
            else:
                self.player_positions[player_id] = {
                    'position': position,
                    'speed': 0,
                    'trajectory': []
                }
        # 检测传球事件
        current_passes = self.detect_passes(frame)
        self.passing_events.extend(current_passes)
        # 分析撞墙式配合
        self.analyze_wall_passes()
        # 在视频上标注结果
        self.annotate_frame(frame)
        return frame
    def detect_passes(self, frame):
        """
        检测传球事件
        """
        passes = []
        # 实现具体的传球检测算法
        # 可以基于:球的速度变化、球员手臂动作、球的方向等
        return passes
    def analyze_wall_passes(self):
        """
        分析最近的传球事件,检测撞墙式配合
        """
        if len(self.passing_events) >= 2:
            last_two = self.passing_events[-2:]
            # 检查是否是来回传球
            if (last_two[0]['from'] == last_two[1]['to'] and 
                last_two[0]['to'] == last_two[1]['from']):
                # 检查时间间隔
                time_diff = last_two[1]['timestamp'] - last_two[0]['timestamp']
                if time_diff < 3.0:  # 3秒内完成
                    self.wall_pass_count += 1
                    # 触发提醒
                    self.trigger_alert(last_two)
    def trigger_alert(self, wall_pass):
        """
        触发撞墙式配合提醒
        """
        print(f"检测到撞墙式配合!")
        print(f"球员: {wall_pass[0]['from']} -> {wall_pass[0]['to']} -> {wall_pass[1]['to']}")
        print(f"时间: {wall_pass[1]['timestamp']}")
    def annotate_frame(self, frame):
        """
        在视频帧上标注撞墙式配合信息
        """
        # 显示统计数据
        cv2.putText(frame, f"Wall Passes: {self.wall_pass_count}", 
                   (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
        return frame
    def calculate_speed(self, pos1, pos2):
        """
        计算球员移动速度
        """
        distance = np.linalg.norm(np.array(pos2) - np.array(pos1))
        return distance

这些代码示例提供了不同层次的撞墙式配合统计方法,你可以根据实际需求选择:

  1. 简单版本:基于事件数据的统计分析
  2. 中级版本:包含数据预处理和详细统计报告
  3. 进阶版本:实时视频分析

需要根据你的具体数据格式和需求进行调整。

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