python案例统计弧线球传中精准度如何?

wen python案例 3

本文目录导读:

python案例统计弧线球传中精准度如何?

  1. 完整案例代码
  2. 扩展功能

我来为您设计一个统计弧线球传中精准度的Python案例,这个案例将模拟足球比赛中的弧线球传中数据,并进行分析统计。

完整案例代码

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime
import random
# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False    # 用来正常显示负号
class CrossPassAnalyzer:
    """弧线球传中分析器"""
    def __init__(self):
        self.data = None
        self.player_stats = None
        self.team_stats = None
    def generate_match_data(self, num_matches=10, players_per_team=11):
        """生成模拟比赛数据"""
        # 定义球员和队伍
        teams = ['皇马', '巴萨', '曼城', '利物浦', '拜仁', '巴黎']
        all_data = []
        match_id = 0
        positions = ['左边锋', '右边锋', '中场', '后卫']
        for match in range(num_matches):
            match_id += 1
            home_team = random.choice(teams)
            away_team = random.choice([t for t in teams if t != home_team])
            # 为每支队伍生成球员
            for team in [home_team, away_team]:
                for player_num in range(1, players_per_team + 1):
                    # 每场比赛每个球员产生10-30次传中
                    num_crosses = random.randint(10, 30)
                    for cross_num in range(num_crosses):
                        # 生成传中数据
                        cross_type = random.choice(['高弧线', '低平弧线', '内旋弧线', '外旋弧线'])
                        # 计算精准度(基于球员能力和随机因素)
                        player_skill = random.uniform(0.5, 0.95)
                        random_factor = random.uniform(-0.1, 0.1)
                        success_probability = max(0, min(1, player_skill + random_factor))
                        data = {
                            'match_id': match_id,
                            'team': team,
                            'opponent': home_team if team == away_team else away_team,
                            'player_number': player_num,
                            'player_position': random.choice(positions),
                            'cross_type': cross_type,
                            'swing_angle': random.randint(30, 75),  # 弧线角度
                            'cross_distance': random.randint(15, 40),  # 传中距离(米)
                            'chip_height': random.randint(10, 30),  # 弧线高度(米)
                            'success': 1 if random.random() < success_probability else 0,
                            'assist': 1 if random.random() < 0.15 and success_probability > 0.7 else 0,
                            'defense_pressure': random.choice(['紧逼', '一般', '自由']),
                            'match_minute': random.randint(1, 95)
                        }
                        all_data.append(data)
        # 转换为DataFrame
        self.data = pd.DataFrame(all_data)
        # 添加更多派生的特征
        self.data['success_rate'] = self.data['success'].mean()
        self.data['distance_bin'] = pd.cut(self.data['cross_distance'], 
                                          bins=[0, 20, 30, 45], 
                                          labels=['短距离', '中距离', '长距离'])
        self.data['angle_bin'] = pd.cut(self.data['swing_angle'],
                                        bins=[0, 45, 60, 76],
                                        labels=['小弧线', '中弧线', '大弧线'])
        return self.data
    def calculate_player_stats(self):
        """计算球员统计数据"""
        if self.data is None:
            raise ValueError("请先生成数据")
        stats = self.data.groupby(['team', 'player_number', 'player_position']).agg({
            'success': ['count', 'sum', 'mean'],
            'assist': 'sum',
            'cross_distance': 'mean',
            'swing_angle': 'mean',
            'chip_height': 'mean'
        }).round(3)
        # 重命名列
        stats.columns = ['总传中', '成功传中', '精准率', '助攻',
                        '平均距离', '平均弧线角度', '平均弧线高度']
        stats = stats.reset_index()
        # 排序按精准率
        stats = stats.sort_values('精准率', ascending=False)
        self.player_stats = stats
        return stats
    def calculate_position_stats(self):
        """计算位置统计"""
        if self.data is None:
            raise ValueError("请先生成数据")
        position_stats = self.data.groupby(['player_position', 'cross_type']).agg({
            'success': ['count', 'sum', 'mean'],
            'team': 'first'
        }).round(3)
        position_stats.columns = ['传中次数', '成功次数', '精准率', '球队']
        position_stats = position_stats.reset_index()
        return position_stats
    def analyze_angle_effect(self):
        """分析弧线角度对精准度的影响"""
        if self.data is None:
            raise ValueError("请先生成数据")
        # 按弧线角度分箱统计
        angle_stats = self.data.groupby(self.data['angle_bin']).agg({
            'success': ['count', 'mean'],
            'assist': 'sum'
        }).round(3)
        angle_stats.columns = ['样本数', '精准率', '助攻数']
        angle_stats = angle_stats.reset_index()
        return angle_stats
    def visualize_results(self):
        """可视化分析结果"""
        if self.player_stats is None:
            self.calculate_player_stats()
        # 创建图表
        fig, axes = plt.subplots(2, 3, figsize=(18, 12))
        # 1. 球员精准率分布
        axes[0, 0].hist(self.player_stats['精准率'], bins=30, alpha=0.7)
        axes[0, 0].set_title('球员传中精准率分布')
        axes[0, 0].set_xlabel('精准率')
        axes[0, 0].set_ylabel('球员数量')
        axes[0, 0].axvline(self.player_stats['精准率'].mean(), 
                          color='r', linestyle='--', label='平均精准率')
        axes[0, 0].legend()
        # 2. 不同位置的精准率比较
        pos_stats = self.player_stats.groupby('player_position')['精准率'].mean()
        axes[0, 1].bar(pos_stats.index, pos_stats.values)
        axes[0, 1].set_title('不同位置的传中精准率')
        axes[0, 1].set_xlabel('位置')
        axes[0, 1].set_ylabel('平均精准率')
        # 3. 弧线角度与精准率的关系
        if hasattr(self, 'data'):
            angle_analysis = self.analyze_angle_effect()
            axes[0, 2].bar(angle_analysis['angle_bin'].astype(str), 
                          angle_analysis['精准率'])
            axes[0, 2].set_title('弧线角度对精准率的影响')
            axes[0, 2].set_xlabel('弧线类型')
            axes[0, 2].set_ylabel('平均精准率')
        # 4. 传中距离对精准率的影响
        distance_analysis = self.data.groupby('distance_bin')['success'].mean()
        axes[1, 0].bar(range(len(distance_analysis)), distance_analysis.values)
        axes[1, 0].set_xticks(range(len(distance_analysis)))
        axes[1, 0].set_xticklabels(distance_analysis.index)
        axes[1, 0].set_title('传中距离对精准率的影响')
        axes[1, 0].set_xlabel('距离类型')
        axes[1, 0].set_ylabel('平均精准率')
        # 5. 各球员的助攻与精准率散点
        axes[1, 1].scatter(self.player_stats['精准率'], 
                          self.player_stats['助攻'],
                          alpha=0.6)
        axes[1, 1].set_title('精准率与助攻关系')
        axes[1, 1].set_xlabel('精准率')
        axes[1, 1].set_ylabel('助攻数')
        # 6. 传中最多的球员Top10
        top_players = self.player_stats.nlargest(10, '总传中')
        axes[1, 2].bar(top_players['player_number'].astype(str), 
                      top_players['总传中'])
        axes[1, 2].set_title('传中最多的球员Top10')
        axes[1, 2].set_xlabel('球员号码')
        axes[1, 2].set_ylabel('总传中次数')
        plt.tight_layout()
        plt.show()
    def generate_report(self):
        """生成统计报告"""
        report = f"""
        ========== 弧线球传中精准度分析报告 ==========
        分析时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
        一、整体统计
        ---------------
        总传中次数: {self.data['success'].count()}
        成功传中: {self.data['success'].sum()}
        整体精准率: {self.data['success'].mean():.3f}
        总助攻数: {self.data['assist'].sum()}
        二、按位置统计
        ---------------
        """
        pos_stats = self.data.groupby(['player_position']).agg({
            'success': ['count', 'mean', 'sum'],
            'assist': 'sum'
        }).round(3)
        for position in pos_stats.index:
            report += f"""\n位置: {position}
        传中次数: {pos_stats.loc[position, ('success', 'count')]}
        精准率: {pos_stats.loc[position, ('success', 'mean')]:.3f}
        助攻数: {pos_stats.loc[position, ('assist', 'sum')]}
        """
        # 添加最佳球员
        best_player = self.player_stats.iloc[0]
        report += f"""
        三、最佳球员
        ---------------
        最佳精准率的球员: 号码 #{best_player['player_number']} ({best_player['player_position']})
        位置: {best_player['player_position']}
        精准率: {best_player['精准率']:.3f}
        """
        return report
# 使用示例
def main():
    """主函数"""
    # 创建分析器
    analyzer = CrossPassAnalyzer()
    # 生成模拟数据
    print("正在生成模拟比赛数据...")
    data = analyzer.generate_match_data(num_matches=50)
    print(f"数据生成完成!共 {len(data)} 次传中记录")
    # 计算统计信息
    print("\n正在计算统计信息...")
    player_stats = analyzer.calculate_player_stats()
    print("球员统计完成!")
    # 输出部分统计
    print("\n===== 球员精准率统计(前10名)=====")
    print(player_stats[['team', 'player_number', 'player_position', '精准率', '助攻']].head(10))
    # 位置统计
    pos_stats = analyzer.calculate_position_stats()
    print("\n===== 位置统计 =====")
    print(pos_stats)
    # 弧线角度分析
    if hasattr(analyzer, 'data'):
        angle_stats = analyzer.analyze_angle_effect()
        print("\n===== 弧线角度影响分析 =====")
        print(angle_stats)
    # 生成报告
    report = analyzer.generate_report()
    print("\n\n", report)
    # 可视化
    analyzer.visualize_results()
    # 提供一些专业建议
    print("\n===== 改进建议 =====")
    suggestions = analyzer.generate_suggestions() if hasattr(analyzer, 'generate_suggestions') else None
    if suggestions:
        print(suggestions)
    else:
        print("1. 从高精准率的球员中,可以重点培养特定位置的传中能力")
        print("2. 分析不同弧线角度下的精准率,优化传球选择")
        print("3. 注意防守压力对传中精准度的影响")
    return analyzer
# 执行主函数
if __name__ == "__main__":
    analyzer = main()

扩展功能

您还可以添加以下功能来增强分析:

def generate_suggestions(self):
    """生成改进建议"""
    suggestions = []
    # 分析最佳位置的传中类型
    best_type = self.data[self.data['success']==1].groupby('cross_type').size().idxmax()
    suggestions.append(f"最成功的传中类型: {best_type}")
    # 分析防守压力影响
    pressure_effect = self.data.groupby('defense_pressure')['success'].mean()
    suggestions.append(f"自由状态下精准率: {pressure_effect['自由']:.3f}")
    suggestions.append(f"紧逼状态下精准率: {pressure_effect['紧逼']:.3f}")
    # 找到最佳传球距离
    distance_effect = self.data.groupby('distance_bin')['success'].mean()
    best_distance = distance_effect.idxmax() if hasattr(distance_effect, 'idxmax') else '中距离'
    suggestions.append(f"最佳传中距离: {best_distance}")
    return "\n".join(suggestions)

这个案例提供了完整的弧线球传中精准度统计分析功能,包括数据生成、统计分析和可视化,您可以根据实际需求调整参数和增加更多分析维度。

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