Python案例统计高球传中争顶成功率?

wen python案例 3

本文目录导读:

Python案例统计高球传中争顶成功率?

  1. 主要功能:
  2. 统计维度包括:
  3. 使用方法:

我将为您创建一个统计足球比赛中高球传中争顶成功率的Python案例,这个案例会模拟处理比赛数据并计算相关统计指标。

import pandas as pd
import numpy as np
from datetime import datetime
class CrossSuccessAnalyzer:
    """
    高球传中争顶成功率分析器
    """
    def __init__(self):
        # 初始化统计数据结构
        self.all_crosses = []
        self.player_stats = {}
        self.team_stats = {}
    def add_cross_event(self, match_id, player_name, team_name, 
                        cross_type, is_successful, defender_count=0,
                        is_set_piece=False, cross_zone=''):
        """
        添加一个传中事件
        参数:
        - match_id: 比赛ID
        - player_name: 球员姓名
        - team_name: 球队名称
        - cross_type: 传中类型 (高球/低平球/地面球)
        - is_successful: 是否成功争顶
        - defender_count: 防守球员数量
        - is_set_piece: 是否定位球
        - cross_zone: 传中区域
        """
        event = {
            'match_id': match_id,
            'player_name': player_name,
            'team_name': team_name,
            'cross_type': cross_type,
            'is_successful': is_successful,
            'defender_count': defender_count,
            'is_set_piece': is_set_piece,
            'cross_zone': cross_zone,
            'timestamp': datetime.now()
        }
        self.all_crosses.append(event)
        # 更新球员统计
        if player_name not in self.player_stats:
            self.player_stats[player_name] = {
                'total': 0, 'successful': 0, 'team': team_name
            }
        self.player_stats[player_name]['total'] += 1
        if is_successful:
            self.player_stats[player_name]['successful'] += 1
        # 更新球队统计
        if team_name not in self.team_stats:
            self.team_stats[team_name] = {
                'total': 0, 'successful': 0, 'high_ball': 0, 'high_success': 0
            }
        self.team_stats[team_name]['total'] += 1
        if cross_type == '高球':
            self.team_stats[team_name]['high_ball'] += 1
            if is_successful:
                self.team_stats[team_name]['high_success'] += 1
    def generate_sample_data(self):
        """
        生成示例数据用于测试
        """
        sample_players = [
            ('梅西', '巴萨'), ('C罗', '皇马'), ('内马尔', '巴萨'),
            ('姆巴佩', '巴黎'), ('哈兰德', '曼城'), ('凯恩', '热刺')
        ]
        # 模拟一场比赛的数据
        for player, team in sample_players:
            # 每个球员进行3-8次传中
            for _ in range(np.random.randint(3, 9)):
                cross_type = np.random.choice(['高球', '低平球', '地面球'], 
                                             p=[0.4, 0.35, 0.25])
                is_successful = np.random.choice([True, False], 
                                                p=[0.4, 0.6])
                self.add_cross_event(
                    match_id='MATCH001',
                    player_name=player,
                    team_name=team,
                    cross_type=cross_type,
                    is_successful=is_successful,
                    defender_count=np.random.randint(0, 5),
                    is_set_piece=np.random.choice([True, False], p=[0.2, 0.8])
                )
    def calculate_success_rate(self, data=None):
        """
        计算成功率
        返回: DataFrame包含各项统计指标
        """
        if data is None:
            data = self.all_crosses
        df = pd.DataFrame(data)
        if df.empty:
            return pd.DataFrame()
        # 计算总体统计
        stats = []
        # 1. 总体传中成功率
        total = len(df)
        successful = df['is_successful'].sum()
        overall_rate = (successful / total * 100) if total > 0 else 0
        stats.append({
            '统计维度': '总传中',
            '总次数': total,
            '成功次数': successful,
            '成功率(%)': round(overall_rate, 2)
        })
        # 2. 高球传中成功率
        high_balls = df[df['cross_type'] == '高球']
        if not high_balls.empty:
            high_total = len(high_balls)
            high_success = high_balls['is_successful'].sum()
            high_rate = (high_success / high_total * 100) if high_total > 0 else 0
            stats.append({
                '统计维度': '高球传中',
                '总次数': high_total,
                '成功次数': high_success,
                '成功率(%)': round(high_rate, 2)
            })
        # 3. 按传中类型统计
        for cross_type in df['cross_type'].unique():
            type_df = df[df['cross_type'] == cross_type]
            type_total = len(type_df)
            type_success = type_df['is_successful'].sum()
            type_rate = (type_success / type_total * 100) if type_total > 0 else 0
            stats.append({
                '统计维度': f'{cross_type}传中',
                '总次数': type_total,
                '成功次数': type_success,
                '成功率(%)': round(type_rate, 2)
            })
        return pd.DataFrame(stats)
    def player_analysis(self, min_crosses=3):
        """
        球员分析
        参数:
        - min_crosses: 最少传中次数(筛选标准)
        返回: 球员排名DataFrame
        """
        player_list = []
        for player, stats in self.player_stats.items():
            if stats['total'] >= min_crosses:
                rate = (stats['successful'] / stats['total'] * 100)
                player_list.append({
                    '球员': player,
                    '球队': stats['team'],
                    '总传中': stats['total'],
                    '成功争顶': stats['successful'],
                    '成功率(%)': round(rate, 2)
                })
        df = pd.DataFrame(player_list)
        if not df.empty:
            df = df.sort_values('成功率(%)', ascending=False).reset_index(drop=True)
        return df
    def team_high_ball_analysis(self):
        """
        球队高球传中分析
        """
        team_list = []
        for team, stats in self.team_stats.items():
            if stats['high_ball'] > 0:
                high_rate = (stats['high_success'] / stats['high_ball'] * 100)
            else:
                high_rate = 0
            total_rate = (stats['successful'] / stats['total'] * 100) if stats['total'] > 0 else 0
            team_list.append({
                '球队': team,
                '总传中': stats['total'],
                '总成功': stats['successful'],
                '总成功率(%)': round(total_rate, 2),
                '高球传中': stats['high_ball'],
                '高球成功': stats['high_success'],
                '高球成功率(%)': round(high_rate, 2)
            })
        df = pd.DataFrame(team_list)
        if not df.empty:
            df = df.sort_values('高球成功率(%)', ascending=False).reset_index(drop=True)
        return df
    def advanced_analysis(self):
        """
        高级分析:考虑多种因素
        """
        df = pd.DataFrame(self.all_crosses)
        if df.empty:
            return {}
        # 1. 防守压力分析
        def pressure_analysis():
            pressure_groups = df.groupby(pd.cut(df['defender_count'], 
                                                bins=[0, 1, 3, 10], 
                                                labels=['低压力(0-1人)', '中等压力(2-3人)', '高压(4+人)']))
            return pressure_groups['is_successful'].agg(['count', 'sum', 'mean']).assign(
                success_rate=lambda x: round(x['mean'] * 100, 2)
            )
        # 2. 定位球vs运动战分析
        def set_piece_analysis():
            set_piece_stats = df.groupby('is_set_piece')['is_successful'].agg(['count', 'sum', 'mean'])
            set_piece_stats.index = ['运动战', '定位球']
            set_piece_stats['success_rate'] = round(set_piece_stats['mean'] * 100, 2)
            return set_piece_stats
        # 3. 区域分析(如果有区域数据)
        def zone_analysis():
            if 'cross_zone' in df.columns and df['cross_zone'].notna().any():
                zone_stats = df.groupby('cross_zone')['is_successful'].agg(['count', 'sum', 'mean'])
                zone_stats['success_rate'] = round(zone_stats['mean'] * 100, 2)
                return zone_stats
            return None
        return {
            '防守压力分析': pressure_analysis(),
            '定位球分析': set_piece_analysis(),
            '区域分析': zone_analysis()
        }
    def generate_report(self):
        """
        生成完整报告
        """
        print("=" * 60)
        print("高球传中争顶成功率分析报告")
        print("=" * 60)
        # 1. 总体统计
        print("\n【总体统计】")
        overall_stats = self.calculate_success_rate()
        print(overall_stats.to_string(index=False))
        # 2. 球员排名
        print("\n【球员排名(最少3次传中)】")
        player_rank = self.player_analysis()
        if not player_rank.empty:
            print(player_rank.to_string(index=False))
        else:
            print("暂无足够数据")
        # 3. 球队分析
        print("\n【球队高球传中分析】")
        team_analysis = self.team_high_ball_analysis()
        if not team_analysis.empty:
            print(team_analysis.to_string(index=False))
        else:
            print("暂无球队数据")
        # 4. 高级分析
        print("\n【高级分析】")
        advanced = self.advanced_analysis()
        print("\n防守压力对成功率的影响:")
        print(advanced['防守压力分析'])
        print("\n定位球vs运动战:")
        print(advanced['定位球分析'])
        if advanced['区域分析'] is not None:
            print("\n传中区域分析:")
            print(advanced['区域分析'])
    def export_to_excel(self, filename='传中争顶分析.xlsx'):
        """
        导出数据到Excel
        """
        with pd.ExcelWriter(filename, engine='openpyxl') as writer:
            # 原始数据
            df = pd.DataFrame(self.all_crosses)
            df.to_excel(writer, sheet_name='原始数据', index=False)
            # 总体统计
            self.calculate_success_rate().to_excel(writer, sheet_name='总体统计', index=False)
            # 球员排名
            self.player_analysis().to_excel(writer, sheet_name='球员排名', index=False)
            # 球队分析
            self.team_high_ball_analysis().to_excel(writer, sheet_name='球队分析', index=False)
            # 高级分析
            advanced = self.advanced_analysis()
            advanced['防守压力分析'].to_excel(writer, sheet_name='防守压力分析')
            advanced['定位球分析'].to_excel(writer, sheet_name='定位球分析')
        print(f"\n数据已导出到 {filename}")
# 使用示例
if __name__ == "__main__":
    # 创建分析器
    analyzer = CrossSuccessAnalyzer()
    # 生成示例数据
    analyzer.generate_sample_data()
    # 生成报告
    analyzer.generate_report()
    # 可选:导出到Excel
    # analyzer.export_to_excel()
    # 或者手动添加数据
    # analyzer.add_cross_event(
    #     match_id='MATCH002',
    #     player_name='测试球员',
    #     team_name='测试队',
    #     cross_type='高球',
    #     is_successful=True,
    #     defender_count=2,
    #     is_set_piece=False,
    #     cross_zone='右路'
    # )

这个案例包含以下功能:

主要功能:

  1. 数据收集 - 记录每次传中事件的详细信息
  2. 成功率计算 - 按不同维度统计成功率
  3. 球员分析 - 个人表现排名
  4. 球队分析 - 球队级别的统计
  5. 高级分析 - 考虑防守压力、定位球等因素

统计维度包括:

  • 总体传中成功率
  • 按传中类型(高球/低平球/地面球)分别统计
  • 球员个人成功率排名
  • 球队高球传中成功率
  • 防守压力对成功率的影响
  • 定位球vs运动战的对比

使用方法:

# 1. 创建分析器
analyzer = CrossSuccessAnalyzer()
# 2. 添加数据(可以手动添加)
analyzer.add_cross_event(
    match_id='MATCH001',
    player_name='球员A',
    team_name='球队X',
    cross_type='高球',
    is_successful=True
)
# 3. 或生成示例数据
analyzer.generate_sample_data()
# 4. 生成分析报告
analyzer.generate_report()

你可以根据实际需求修改:

  • 添加更多数据维度(如跑动距离、起跳高度等)
  • 修改筛选条件
  • 调整统计方法
  • 扩展分析功能(如时间序列分析、趋势分析等)

上一篇这个Python案例显示低平球传中次数?

下一篇当前分类已是最新一篇

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