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

wen python案例 1

本文目录导读:

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

  1. 数据模型设计
  2. 统计分析函数
  3. 使用示例

我来为您提供一个统计门球短传配合成功率的Python案例。

数据模型设计

import pandas as pd
import numpy as np
from datetime import datetime
import matplotlib.pyplot as plt
import seaborn as sns
class ShortPassData:
    """短传配合数据模型"""
    def __init__(self):
        self.data = []
    def add_pass(self, game_id, attacker, passer, receiver, 
                 distance, pressure_level, success, time_minute):
        """添加单次传球记录"""
        self.data.append({
            'game_id': game_id,
            'attacker': attacker,
            'passer': passer,
            'receiver': receiver,
            'distance': distance,
            'pressure_level': pressure_level,  # 1-5, 5为最高压力
            'success': success,  # True/False
            'time_minute': time_minute
        })
    def to_dataframe(self):
        """转换为DataFrame"""
        return pd.DataFrame(self.data)
# 创建模拟数据
def generate_sample_data():
    """生成模拟的门球短传数据"""
    data = ShortPassData()
    # 模拟10场比赛的数据
    np.random.seed(42)
    players = ['Player_A', 'Player_B', 'Player_C', 'Player_D', 'Player_E']
    for game in range(1, 11):
        for _ in range(np.random.randint(20, 40)):  # 每场20-40次短传
            passer = np.random.choice(players)
            receiver = np.random.choice([p for p in players if p != passer])
            data.add_pass(
                game_id=f'Game_{game:02d}',
                attacker='Team1',
                passer=passer,
                receiver=receiver,
                distance=np.random.uniform(1, 15),  # 1-15米短传
                pressure_level=np.random.randint(1, 6),
                success=np.random.random() > 0.3,  # 70%成功率基线
                time_minute=np.random.randint(1, 91)
            )
    return data.to_dataframe()

统计分析函数

class ShortPassAnalyzer:
    """短传配合分析器"""
    def __init__(self, df):
        self.df = df
        self.total_passes = len(df)
        self.successful_passes = df[df['success'] == True].shape[0]
    def overall_success_rate(self):
        """总体成功率"""
        rate = self.successful_passes / self.total_passes * 100
        return {
            'total_passes': self.total_passes,
            'successful_passes': self.successful_passes,
            'success_rate': round(rate, 2)
        }
    def player_success_rate(self):
        """球员个人成功率"""
        player_stats = []
        for player in self.df['passer'].unique():
            player_passes = self.df[self.df['passer'] == player]
            total = len(player_passes)
            success = player_passes['success'].sum()
            rate = (success / total * 100) if total > 0 else 0
            player_stats.append({
                'player': player,
                'total_passes': total,
                'successful_passes': success,
                'success_rate': round(rate, 2)
            })
        return pd.DataFrame(player_stats)
    def distance_analysis(self):
        """距离分析"""
        # 按距离区间分组
        distance_bins = [0, 3, 6, 9, 12, 15]
        labels = ['0-3m', '3-6m', '6-9m', '9-12m', '12-15m']
        self.df['distance_group'] = pd.cut(
            self.df['distance'], 
            bins=distance_bins, 
            labels=labels
        )
        distance_stats = []
        for group in labels:
            group_data = self.df[self.df['distance_group'] == group]
            total = len(group_data)
            success = group_data['success'].sum() if total > 0 else 0
            rate = (success / total * 100) if total > 0 else 0
            distance_stats.append({
                'distance_group': group,
                'total_passes': total,
                'successful_passes': success,
                'success_rate': round(rate, 2)
            })
        return pd.DataFrame(distance_stats)
    def pressure_analysis(self):
        """压力等级分析"""
        pressure_stats = []
        for level in range(1, 6):
            level_data = self.df[self.df['pressure_level'] == level]
            total = len(level_data)
            success = level_data['success'].sum() if total > 0 else 0
            rate = (success / total * 100) if total > 0 else 0
            pressure_stats.append({
                'pressure_level': level,
                'total_passes': total,
                'successful_passes': success,
                'success_rate': round(rate, 2)
            })
        return pd.DataFrame(pressure_stats)
    def game_progression_analysis(self):
        """比赛进程分析(每15分钟分段)"""
        time_bins = [0, 15, 30, 45, 60, 75, 90]
        labels = ['0-15min', '15-30min', '30-45min', '45-60min', '60-75min', '75-90min']
        self.df['time_group'] = pd.cut(
            self.df['time_minute'], 
            bins=time_bins, 
            labels=labels
        )
        time_stats = []
        for group in labels:
            group_data = self.df[self.df['time_group'] == group]
            total = len(group_data)
            success = group_data['success'].sum() if total > 0 else 0
            rate = (success / total * 100) if total > 0 else 0
            time_stats.append({
                'time_period': group,
                'total_passes': total,
                'successful_passes': success,
                'success_rate': round(rate, 2)
            })
        return pd.DataFrame(time_stats)
    def partner_analysis(self):
        """球员配合分析"""
        partner_stats = []
        for passer in self.df['passer'].unique():
            for receiver in self.df['receiver'].unique():
                if passer != receiver:
                    pairs = self.df[
                        (self.df['passer'] == passer) & 
                        (self.df['receiver'] == receiver)
                    ]
                    total = len(pairs)
                    if total > 0:
                        success = pairs['success'].sum()
                        rate = (success / total * 100)
                        partner_stats.append({
                            'passer': passer,
                            'receiver': receiver,
                            'total_passes': total,
                            'successful_passes': success,
                            'success_rate': round(rate, 2)
                        })
        return pd.DataFrame(partner_stats)
# 生成报告函数
def generate_analysis_report(analyzer):
    """生成分析报告"""
    print("=" * 60)
    print("门球短传配合统计报告")
    print("=" * 60)
    # 1. 总体统计
    print("\n1. 总体成功率")
    print("-" * 40)
    overall = analyzer.overall_success_rate()
    print(f"总传球次数: {overall['total_passes']}")
    print(f"成功传球次数: {overall['successful_passes']}")
    print(f"总体成功率: {overall['success_rate']}%")
    # 2. 球员统计
    print("\n2. 球员个人成功率")
    print("-" * 40)
    player_stats = analyzer.player_success_rate()
    print(player_stats.to_string(index=False))
    # 3. 距离分析
    print("\n3. 传球距离分析")
    print("-" * 40)
    distance_stats = analyzer.distance_analysis()
    print(distance_stats.to_string(index=False))
    # 4. 压力分析
    print("\n4. 压力等级分析")
    print("-" * 40)
    pressure_stats = analyzer.pressure_analysis()
    print(pressure_stats.to_string(index=False))
    # 5. 比赛进程分析
    print("\n5. 比赛进程分析")
    print("-" * 40)
    time_stats = analyzer.game_progression_analysis()
    print(time_stats.to_string(index=False))
# 可视化函数
def create_visualizations(analyzer):
    """创建可视化图表"""
    fig, axes = plt.subplots(2, 2, figsize=(15, 12))
    # 1. 球员成功率对比
    ax1 = axes[0, 0]
    player_stats = analyzer.player_success_rate()
    ax1.bar(player_stats['player'], player_stats['success_rate'])
    ax1.set_title('球员短传成功率对比')
    ax1.set_xlabel('球员')
    ax1.set_ylabel('成功率 (%)')
    ax1.set_ylim(0, 100)
    for i, v in enumerate(player_stats['success_rate']):
        ax1.text(i, v + 1, f'{v}%', ha='center')
    # 2. 距离与成功率关系
    ax2 = axes[0, 1]
    distance_stats = analyzer.distance_analysis()
    ax2.plot(distance_stats['distance_group'], 
             distance_stats['success_rate'], 
             marker='o', linewidth=2, markersize=8)
    ax2.set_title('传球距离与成功率关系')
    ax2.set_xlabel('距离分组')
    ax2.set_ylabel('成功率 (%)')
    ax2.set_ylim(0, 100)
    # 3. 压力等级影响
    ax3 = axes[1, 0]
    pressure_stats = analyzer.pressure_analysis()
    ax3.bar(pressure_stats['pressure_level'].astype(str), 
            pressure_stats['success_rate'])
    ax3.set_title('防守压力对成功率的影响')
    ax3.set_xlabel('压力等级 (1-5)')
    ax3.set_ylabel('成功率 (%)')
    ax3.set_ylim(0, 100)
    # 4. 比赛进程趋势
    ax4 = axes[1, 1]
    time_stats = analyzer.game_progression_analysis()
    ax4.plot(time_stats['time_period'], 
             time_stats['success_rate'], 
             marker='s', linewidth=2, markersize=8, color='green')
    ax4.set_title('比赛进程成功率变化')
    ax4.set_xlabel('时间分段')
    ax4.set_ylabel('成功率 (%)')
    ax4.set_ylim(0, 100)
    plt.tight_layout()
    plt.show()
# 主程序
if __name__ == "__main__":
    # 生成数据
    print("正在生成模拟数据...")
    df = generate_sample_data()
    # 创建分析器
    analyzer = ShortPassAnalyzer(df)
    # 生成报告
    generate_analysis_report(analyzer)
    # 创建可视化
    create_visualizations(analyzer)
    # 额外分析:最佳配合组合
    print("\n6. 最佳配合组合(Top 5)")
    print("-" * 40)
    partner_stats = analyzer.partner_analysis()
    top_partners = partner_stats.nlargest(5, 'success_rate')
    print(top_partners.to_string(index=False))

使用示例

# 简单的使用示例
if __name__ == "__main__":
    # 生成数据
    data = generate_sample_data()
    # 创建分析器
    analyzer = ShortPassAnalyzer(data)
    # 获取总体成功率
    print("总体成功率:", analyzer.overall_success_rate())
    # 查看球员数据
    player_stats = analyzer.player_success_rate()
    print("\n球员统计:")
    print(player_stats)
    # 查看距离分析
    distance_stats = analyzer.distance_analysis()
    print("\n距离分析:")
    print(distance_stats)

这个案例提供了完整的门球短传配合统计框架,包括:

  1. 数据收集:模拟球员传球数据
  2. 多维度分析:球员、距离、压力、比赛进程等
  3. 可视化报告:图表展示分析结果
  4. 配合分析:统计球员间配合成功率

您可以根据实际数据格式调整数据导入方式,并根据需要扩展更多分析维度。

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