python案例统计门球短传配合成功率?

wen python案例 2

本文目录导读:

python案例统计门球短传配合成功率?

  1. 主要功能:
  2. 扩展建议:

我来为您设计一个门球短传配合成功率的统计系统,这个案例将包含数据输入、统计分析、可视化展示等功能。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime
import json
import os
class GateballPassingAnalyzer:
    """门球短传配合成功率分析系统"""
    def __init__(self):
        self.passes_data = []
        self.players = {}
        self.teams = {}
    def add_pass_record(self, team_name, passer, receiver, 
                       pass_type='short', distance=0, 
                       is_success=True, position=None, 
                       defense_pressure=False, match_id=None):
        """
        添加传球记录
        参数:
        - team_name: 队伍名称
        - passer: 传球队员
        - receiver: 接球队员
        - pass_type: 传球类型 (short/medium/long)
        - distance: 传球距离(米)
        - is_success: 是否成功
        - position: 传球位置
        - defense_pressure: 是否有防守压力
        - match_id: 比赛编号
        """
        record = {
            'timestamp': datetime.now(),
            'team': team_name,
            'passer': passer,
            'receiver': receiver,
            'pass_type': pass_type,
            'distance': distance,
            'success': is_success,
            'position': position,
            'defense_pressure': defense_pressure,
            'match_id': match_id
        }
        self.passes_data.append(record)
    def analyze_short_pass_success_rate(self, team_name=None):
        """
        分析短传成功率
        统计不同维度的短传成功率
        """
        df = pd.DataFrame(self.passes_data)
        # 筛选短传数据
        short_passes = df[df['pass_type'] == 'short']
        if team_name:
            short_passes = short_passes[short_passes['team'] == team_name]
        if len(short_passes) == 0:
            return None
        # 总体成功率
        total_success_rate = short_passes['success'].mean() * 100
        # 按比赛统计
        match_stats = short_passes.groupby('match_id').agg({
            'success': ['count', 'sum', 'mean']
        }).round(3)
        # 按队伍统计
        team_stats = short_passes.groupby('team').agg({
            'success': ['count', 'sum', 'mean']
        }).round(3)
        # 按距离区间统计
        short_passes['distance_range'] = pd.cut(
            short_passes['distance'], 
            bins=[0, 5, 10, 15, 20], 
            labels=['0-5m', '5-10m', '10-15m', '15-20m']
        )
        distance_stats = short_passes.groupby('distance_range')['success'].agg(
            ['count', 'mean']
        ).round(3)
        # 按防守压力统计
        pressure_stats = short_passes.groupby('defense_pressure')['success'].agg(
            ['count', 'mean']
        ).round(3)
        return {
            'total_success_rate': total_success_rate,
            'total_passes': len(short_passes),
            'match_stats': match_stats,
            'team_stats': team_stats,
            'distance_stats': distance_stats,
            'pressure_stats': pressure_stats,
            'raw_data': short_passes
        }
    def analyze_player_passing(self, team_name, player_name):
        """
        分析指定队员的短传表现
        """
        df = pd.DataFrame(self.passes_data)
        # 该队员作为传球者的短传
        passer_data = df[
            (df['team'] == team_name) & 
            (df['passer'] == player_name) & 
            (df['pass_type'] == 'short')
        ]
        # 该队员作为接球者的短传
        receiver_data = df[
            (df['team'] == team_name) & 
            (df['receiver'] == player_name) & 
            (df['pass_type'] == 'short')
        ]
        # 传球成功率和接球成功率
        pass_success_rate = passer_data['success'].mean() * 100 if len(passer_data) > 0 else 0
        receive_success_rate = receiver_data['success'].mean() * 100 if len(receiver_data) > 0 else 0
        # 统计不同接球对象的成功率
        if len(passer_data) > 0:
            target_stats = passer_data.groupby('receiver')['success'].agg(['count', 'mean']).round(3)
        else:
            target_stats = None
        return {
            'player': player_name,
            'team': team_name,
            'pass_attempts': len(passer_data),
            'pass_success': passer_data['success'].sum() if len(passer_data) > 0 else 0,
            'pass_success_rate': pass_success_rate,
            'receive_attempts': len(receiver_data),
            'receive_success': receiver_data['success'].sum() if len(receiver_data) > 0 else 0,
            'receive_success_rate': receive_success_rate,
            'target_stats': target_stats
        }
    def analyze_combination_pairs(self, team_name=None):
        """
        分析传球组合(谁传给谁最成功)
        """
        df = pd.DataFrame(self.passes_data)
        if team_name:
            df = df[df['team'] == team_name]
        df = df[df['pass_type'] == 'short']
        # 创建组合标识
        df['combination'] = df['passer'] + ' -> ' + df['receiver']
        # 统计组合成功率
        combination_stats = df.groupby('combination').agg({
            'success': ['count', 'sum', 'mean']
        }).round(3)
        combination_stats.columns = ['次数', '成功次数', '成功率']
        combination_stats = combination_stats.sort_values('次数', ascending=False)
        return combination_stats
    def visualize_results(self, results, save_path=None):
        """
        可视化分析结果
        """
        if not results:
            print("没有可用的数据")
            return
        fig, axes = plt.subplots(2, 3, figsize=(15, 10))
        fig.suptitle('门球短传配合成功率分析', fontsize=16)
        # 1. 总体成功率饼图
        ax1 = axes[0, 0]
        success_count = results['total_passes'] * results['total_success_rate'] / 100
        fail_count = results['total_passes'] - success_count
        ax1.pie([success_count, fail_count], 
                labels=['成功', '失败'], 
                autopct='%1.1f%%',
                colors=['#2ecc71', '#e74c3c'])
        ax1.set_title(f'总体成功率: {results["total_success_rate"]:.1f}%\n总次数: {results["total_passes"]}')
        # 2. 距离区间成功率柱状图
        ax2 = axes[0, 1]
        distance_stats = results['distance_stats']
        ax2.bar(distance_stats.index.astype(str), 
                distance_stats['mean'] * 100,
                color='#3498db')
        ax2.set_ylabel('成功率 (%)')
        ax2.set_title('不同距离的成功率')
        ax2.set_ylim([0, 100])
        # 3. 防守压力对比图
        ax3 = axes[0, 2]
        pressure_stats = results['pressure_stats']
        pressure_labels = ['无压力' if not x else '有压力' for x in pressure_stats.index]
        ax3.bar(pressure_labels, 
                pressure_stats['mean'] * 100,
                color=['#9b59b6', '#e67e22'])
        ax3.set_ylabel('成功率 (%)')
        ax3.set_title('防守压力对成功率的影响')
        ax3.set_ylim([0, 100])
        # 4. 队伍间对比
        ax4 = axes[1, 0]
        team_stats = results['team_stats']
        if len(team_stats) > 0:
            team_names = [x[0] for x in team_stats.index]
            team_rates = [x[2] * 100 for x in team_stats.values]
            ax4.bar(team_names, team_rates)
            ax4.set_ylabel('成功率 (%)')
            ax4.set_title('各队伍成功率对比')
            ax4.set_ylim([0, 100])
        # 5. 比赛趋势(如果有多场比赛)
        ax5 = axes[1, 1]
        match_stats = results['match_stats']
        if len(match_stats) > 0:
            match_ids = [x[0] for x in match_stats.index]
            match_rates = [x[2] * 100 for x in match_stats.values]
            ax5.plot(match_ids, match_rates, marker='o', linewidth=2)
            ax5.set_ylabel('成功率 (%)')
            ax5.set_title('各场比赛短传成功率趋势')
            ax5.set_ylim([0, 100])
            ax5.tick_params(axis='x', rotation=45)
        # 6. 传球组合热力图
        ax6 = axes[1, 2]
        combo_stats = self.analyze_combination_pairs()
        if len(combo_stats) > 0:
            top_combos = combo_stats.head(10)
            ax6.barh(top_combos.index, top_combos['成功率'] * 100, color='#1abc9c')
            ax6.set_xlabel('成功率 (%)')
            ax6.set_title('最佳传球组合(前10)')
            ax6.set_xlim([0, 100])
        plt.tight_layout()
        if save_path:
            plt.savefig(save_path, dpi=300, bbox_inches='tight')
            print(f"图表已保存至: {save_path}")
        else:
            plt.show()
    def export_report(self, file_path, results=None):
        """
        导出详细报告
        """
        if not results:
            results = self.analyze_short_pass_success_rate()
        with open(file_path, 'w', encoding='utf-8') as f:
            f.write("=" * 50 + "\n")
            f.write("门球短传配合成功率分析报告\n")
            f.write(f"生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
            f.write("=" * 50 + "\n\n")
            # 总体统计
            f.write("【总体统计】\n")
            f.write(f"总传球次数: {results['total_passes']}\n")
            f.write(f"总体成功率: {results['total_success_rate']:.2f}%\n\n")
            # 按距离统计
            f.write("【按距离统计】\n")
            f.write(results['distance_stats'].to_string())
            f.write("\n\n")
            # 按防守压力统计
            f.write("【防守压力分析】\n")
            f.write(results['pressure_stats'].to_string())
            f.write("\n\n")
            # 按队伍统计
            f.write("【队伍统计】\n")
            f.write(results['team_stats'].to_string())
            f.write("\n\n")
            # 最佳组合
            f.write("【最佳传球组合 TOP10】\n")
            combo_stats = self.analyze_combination_pairs()
            f.write(combo_stats.head(10).to_string())
            f.write("\n")
        print(f"报告已导出至: {file_path}")
# 使用示例
def demo_usage():
    """演示使用方法"""
    analyzer = GateballPassingAnalyzer()
    # 模拟一些数据
    import random
    random.seed(42)
    teams = ['红队', '蓝队']
    players_red = ['张三', '李四', '王五', '赵六', '孙七']
    players_blue = ['周八', '吴九', '郑十', '陈十一', '刘十二']
    # 生成模拟数据
    for match in range(1, 4):
        for i in range(100):  # 每场比赛100次传球
            team = random.choice(teams)
            if team == '红队':
                players = players_red
            else:
                players = players_blue
            passer = random.choice(players)
            receiver = random.choice([p for p in players if p != passer])
            # 80%为短传
            pass_type = 'short' if random.random() < 0.8 else 'medium'
            if pass_type == 'short':
                distance = random.uniform(1, 15)
            else:
                distance = random.uniform(15, 25)
            success = random.random() < 0.7  # 70%基础成功率
            defense_pressure = random.random() < 0.3  # 30%有防守压力
            analyzer.add_pass_record(
                team_name=team,
                passer=passer,
                receiver=receiver,
                pass_type=pass_type,
                distance=distance,
                is_success=success,
                defense_pressure=defense_pressure,
                match_id=f'M{match}'
            )
    # 分析
    results = analyzer.analyze_short_pass_success_rate()
    # 可视化
    analyzer.visualize_results(results, save_path='short_pass_analysis.png')
    # 导出报告
    analyzer.export_report('short_pass_report.txt', results)
    # 查看某个队员的表现
    player_analysis = analyzer.analyze_player_passing('红队', '张三')
    print(f"\n张三的传球分析:")
    print(f"传球次数: {player_analysis['pass_attempts']}")
    print(f"传球成功率: {player_analysis['pass_success_rate']:.2f}%")
    print(f"接球次数: {player_analysis['receive_attempts']}")
    print(f"接球成功率: {player_analysis['receive_success_rate']:.2f}%")
    # 查看最佳组合
    print("\n最佳传球组合:")
    combo_stats = analyzer.analyze_combination_pairs()
    print(combo_stats.head(5))
    return analyzer, results
if __name__ == "__main__":
    analyzer, results = demo_usage()

这个门球短传配合成功率分析系统具有以下特点:

主要功能:

  1. 数据记录功能

    • 记录传球人、接球人、传球类型、距离、是否成功等详细信息
    • 支持多场比赛数据管理
    • 记录防守压力等复杂因素
  2. 统计分析功能

    • 整体成功率统计
    • 按距离分组的成功率分析
    • 按防守压力对比
    • 队伍间对比分析
    • 个人传球和接球表现
    • 传球组合分析(谁传给谁最成功)
  3. 可视化展示

    • 成功率饼图
    • 距离-成功率柱状图
    • 防守压力影响图
    • 队伍对比柱状图
    • 比赛趋势折线图
    • 最佳组合条形图
  4. 报告导出

    • 自动生成详细分析报告
    • 支持导出为文本文件

扩展建议:

  1. 添加更多分析维度

    # 可以添加按位置分析
    def analyze_by_position(self):
     positions = ['前场', '中场', '后场']
     # 分析不同位置的成功率
  2. 实时数据输入界面

    # 可以添加GUI界面
    import tkinter as tk
    # 创建简单的数据输入表单
  3. 机器学习预测

    # 使用历史数据预测成功率
    from sklearn.linear_model import LogisticRegression
    # 根据距离、防守压力等特征预测成功率
  4. 视频分析集成

    # 可以集成视频分析模块
    import cv2
    # 自动识别传球动作

这个系统可以根据实际需求进行扩展和修改,支持不同的使用场景。

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