python案例统计高位逼抢夺回球权几次?

wen python案例 1

本文目录导读:

python案例统计高位逼抢夺回球权几次?

  1. 完整案例代码
  2. 关键功能说明

我来帮你创建一个统计高位逼抢中夺回球权次数的Python案例,这个案例会模拟比赛数据并进行分析。

完整案例代码

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from dataclasses import dataclass
from typing import List, Dict, Tuple
import random
@dataclass
class BallRecovery:
    """球权恢复数据类"""
    minute: int
    player: str
    zone: str
    recovery_type: str
    opponent_team: str
    pressure_level: str
    outcome: str
    is_high_press: bool  # 是否是高位逼抢
class HighPressAnalyzer:
    """高位逼抢球权恢复分析器"""
    def __init__(self):
        self.recoveries = []
        self.high_press_count = 0
        self.total_count = 0
    def generate_match_data(self, num_events=100):
        """生成模拟比赛数据"""
        players = ['张伟', '李强', '王浩', '刘洋', '陈晨', 
                   '赵磊', '孙明', '周军', '吴刚', '郑凯']
        zones = ['前场左路', '前场中路', '前场右路',
                '中场左路', '中场中路', '中场右路',
                '后场左路', '后场中路', '后场右路']
        recovery_types = ['抢断', '拦截', '争顶', '解围']
        outcomes = ['传球', '射门', '控球', '犯规', '出界']
        self.recoveries = []
        for _ in range(num_events):
            minute = random.randint(1, 90)
            player = random.choice(players)
            zone = random.choice(zones)
            recovery_type = random.choice(recovery_types)
            outcome = random.choice(outcomes)
            # 判断是否为高位逼抢(前场和中场区域)
            is_high_press = zone.startswith(('前场', '中场'))
            # 压力等级基于位置
            if zone.startswith('前场'):
                pressure_level = '高强度'
            elif zone.startswith('中场'):
                pressure_level = '中等强度' if random.random() < 0.5 else '高强度'
            else:
                pressure_level = '低强度'
            recovery = BallRecovery(
                minute=minute,
                player=player,
                zone=zone,
                recovery_type=recovery_type,
                opponent_team='对手队',
                pressure_level=pressure_level,
                outcome=outcome,
                is_high_press=is_high_press
            )
            self.recoveries.append(recovery)
            self.total_count += len(self.recoveries)
    def count_high_press_recoveries(self) -> Dict:
        """统计高位逼抢夺回球权次数"""
        # 筛选高位逼抢的球权恢复
        high_press_recoveries = [r for r in self.recoveries if r.is_high_press]
        self.high_press_count = len(high_press_recoveries)
        return {
            'total_recoveries': len(self.recoveries),
            'high_press_recoveries': self.high_press_count,
            'percentage': f"{self.high_press_count / len(self.recoveries) * 100:.1f}%"
        }
    def analyze_by_zone(self) -> pd.DataFrame:
        """按区域分析球权恢复"""
        df = pd.DataFrame([vars(r) for r in self.recoveries])
        # 分离前场、中场、后场
        df['area'] = df['zone'].apply(lambda x: x[:2])
        zone_stats = df.groupby(['area', 'is_high_press']).size().reset_index(name='count')
        zone_pivot = zone_stats.pivot(index='area', columns='is_high_press', values='count')
        zone_pivot = zone_pivot.fillna(0)
        zone_pivot.columns = ['非高位逼抢', '高位逼抢']
        zone_pivot['总计'] = zone_pivot.sum(axis=1)
        zone_pivot['高位占比'] = zone_pivot['高位逼抢'] / zone_pivot['总计'] * 100
        return zone_pivot
    def analyze_by_player(self) -> pd.DataFrame:
        """按球员分析球权恢复"""
        df = pd.DataFrame([vars(r) for r in self.recoveries])
        high_press_df = df[df['is_high_press']]
        player_stats = high_press_df.groupby('player').agg({
            'minute': 'count',
            'recovery_type': lambda x: ', '.join(x.unique())
        }).rename(columns={'minute': '高位逼抢次数', 'recovery_type': '恢复方式'})
        player_stats = player_stats.sort_values('高位逼抢次数', ascending=False)
        return player_stats
    def analyze_over_time(self) -> pd.DataFrame:
        """按时间分析球权恢复"""
        df = pd.DataFrame([vars(r) for r in self.recoveries])
        # 按15分钟分段
        df['period'] = pd.cut(df['minute'], bins=[0, 15, 30, 45, 60, 75, 90],
                              labels=['0-15', '15-30', '30-45', '45-60', '60-75', '75-90'])
        over_time = df[df['is_high_press']].groupby('period').size().reset_index(name='次数')
        over_time['占比'] = over_time['次数'] / over_time['次数'].sum() * 100
        return over_time
    def visualize_results(self):
        """可视化统计结果"""
        fig, axes = plt.subplots(2, 2, figsize=(15, 12))
        # 1. 总体统计饼图
        ax1 = axes[0, 0]
        high_press = self.high_press_count
        normal_press = self.total_count - high_press
        ax1.pie([high_press, normal_press], 
               labels=['高位逼抢', '其他情况'],
               autopct='%1.1f%%',
               colors=['#FF6B6B', '#4ECDC4'],
               explode=(0.05, 0))
        ax1.set_title(f'总体球权恢复分布 (总次数: {self.total_count})')
        # 2. 区域分析柱状图
        ax2 = axes[0, 1]
        zone_data = self.analyze_by_zone()
        x = np.arange(len(zone_data.index))
        width = 0.35
        ax2.bar(x - width/2, zone_data['高位逼抢'], width, label='高位逼抢', color='#FF6B6B')
        ax2.bar(x + width/2, zone_data['非高位逼抢'], width, label='非高位逼抢', color='#4ECDC4')
        ax2.set_xlabel('比赛区域')
        ax2.set_ylabel('次数')
        ax2.set_title('各区域球权恢复对比')
        ax2.set_xticks(x)
        ax2.set_xticklabels(zone_data.index)
        ax2.legend()
        # 3. 球员表现条形图
        ax3 = axes[1, 0]
        player_data = self.analyze_by_player()
        if not player_data.empty:
            ax3.barh(player_data.head(5).index, player_data['高位逼抢次数'].head(5), color='#FF6B6B')
            ax3.set_xlabel('次数')
            ax3.set_title('高位逼抢球权恢复Top5球员')
            ax3.invert_yaxis()  # 让最多的在上面
        # 4. 时间趋势图
        ax4 = axes[1, 1]
        time_data = self.analyze_over_time()
        ax4.plot(time_data['period'], time_data['次数'], marker='o', linewidth=2, color='#FF6B6B')
        ax4.fill_between(time_data['period'], time_data['次数'], alpha=0.3, color='#FF6B6B')
        ax4.set_xlabel('比赛时间段')
        ax4.set_ylabel('高位逼抢次数')
        ax4.set_title('比赛不同阶段的高位逼抢球权恢复')
        ax4.grid(True, alpha=0.3)
        plt.tight_layout()
        plt.show()
class MatchReporter:
    """生成比赛报告类"""
    def __init__(self, analyzer: HighPressAnalyzer):
        self.analyzer = analyzer
    def generate_report(self) -> str:
        """生成分析报告"""
        stats = self.analyzer.count_high_press_recoveries()
        zone_data = self.analyzer.analyze_by_zone()
        player_data = self.analyzer.analyze_by_player()
        report = f"""
        ========== 高位逼抢球权恢复分析报告 ==========
        【总体统计】
        总球权恢复次数:{stats['total_recoveries']} 次
        高位逼抢恢复:{stats['high_press_recoveries']} 次
        占比:{stats['percentage']}
        【区域分析】
        {zone_data.to_string()}
        【球员贡献】
        {player_data.to_string()}
        【
        1. 高位逼抢成功率:{stats['percentage']}
        2. 最高效逼抢区域:{zone_data['高位逼抢'].idxmax()}
        3. 最佳逼抢球员:{player_data.index[0] if not player_data.empty else '暂无数据'}
        ========================================
        """
        return report
# 使用示例
def main():
    # 创建分析器
    analyzer = HighPressAnalyzer()
    # 生成模拟数据
    print("正在生成模拟比赛数据...")
    analyzer.generate_match_data(num_events=150)
    # 统计高位逼抢球权恢复
    stats = analyzer.count_high_press_recoveries()
    print("\n=== 高位逼抢球权恢复统计 ===")
    print(f"总球权恢复次数: {stats['total_recoveries']}")
    print(f"高位逼抢恢复次数: {stats['high_press_recoveries']}")
    print(f"高位逼抢占比: {stats['percentage']}")
    # 区域分析
    print("\n=== 按区域分析 ===")
    zone_data = analyzer.analyze_by_zone()
    print(zone_data)
    # 球员分析
    print("\n=== 按球员分析 ===")
    player_data = analyzer.analyze_by_player()
    print(player_data)
    # 时间分析
    print("\n=== 按时间段分析 ===")
    time_data = analyzer.analyze_over_time()
    print(time_data)
    # 生成报告
    reporter = MatchReporter(analyzer)
    print("\n" + reporter.generate_report())
    # 可视化
    analyzer.visualize_results()
    # 额外:保存详细数据到CSV
    save_recovery_data(analyzer.recoveries, "high_press_recoveries.csv")
def save_recovery_data(recoveries: List[BallRecovery], filename: str):
    """保存恢复数据到CSV文件"""
    data = []
    for r in recoveries:
        data.append({
            '时间(分钟)': r.minute,
            '球员': r.player,
            '区域': r.zone,
            '恢复方式': r.recovery_type,
            '压力等级': r.pressure_level,
            '后续发展': r.outcome,
            '是否高位逼抢': '是' if r.is_high_press else '否'
        })
    df = pd.DataFrame(data)
    df.to_csv(filename, index=False, encoding='utf-8-sig')
    print(f"\n数据已保存到: {filename}")
if __name__ == "__main__":
    main()

关键功能说明

数据生成

  • 模拟生成比赛的球权恢复数据
  • 包含位置、球员、区域、方式等信息

核心统计功能

  • count_high_press_recoveries(): 统计高位逼抢总次数
  • analyze_by_zone(): 按区域分析
  • analyze_by_player(): 按球员分析
  • analyze_over_time(): 按时间段分析

可视化

  • 饼图显示总体分布
  • 柱状图对比不同区域
  • 排名图显示最佳球员
  • 趋势图分析时间分布

报告生成

  • 自动生成详细分析报告
  • 保存数据到CSV文件

运行这个代码后,你会得到详细的统计结果和可视化图表,清楚地看到高位逼抢夺回球权的次数和分布情况。

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