python案例统计赛季累计数据对比如何?

wen python案例 1

本文目录导读:

python案例统计赛季累计数据对比如何?

  1. 基础数据类设计
  2. 模拟赛季数据生成
  3. 数据分析和可视化
  4. 主程序示例
  5. 输出示例

我来为您设计一个统计赛季累计数据对比的Python案例,这个案例将模拟NBA/篮球赛季的数据统计和对比分析:

基础数据类设计

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime
import warnings
warnings.filterwarnings('ignore')
# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
class PlayerStats:
    """球员赛季数据类"""
    def __init__(self, name, team):
        self.name = name
        self.team = team
        self.games = []
        self.total_stats = {
            'points': 0, 'rebounds': 0, 'assists': 0,
            'steals': 0, 'blocks': 0, 'turnovers': 0,
            'fga': 0, 'fgm': 0, '3pa': 0, '3pm': 0,
            'fta': 0, 'ftm': 0, 'minutes': 0
        }
    def add_game(self, game_stats):
        """添加单场比赛数据"""
        self.games.append(game_stats)
        for key in self.total_stats:
            self.total_stats[key] += game_stats.get(key, 0)
    def get_averages(self):
        """计算场均数据"""
        games_played = len(self.games)
        if games_played == 0:
            return {}
        averages = {}
        for key, value in self.total_stats.items():
            averages[key] = round(value / games_played, 2)
        # 计算命中率
        if self.total_stats['fga'] > 0:
            averages['fg_pct'] = round(self.total_stats['fgm'] / self.total_stats['fga'] * 100, 1)
        if self.total_stats['3pa'] > 0:
            averages['3p_pct'] = round(self.total_stats['3pm'] / self.total_stats['3pa'] * 100, 1)
        if self.total_stats['fta'] > 0:
            averages['ft_pct'] = round(self.total_stats['ftm'] / self.total_stats['fta'] * 100, 1)
        return averages

模拟赛季数据生成

class SeasonStats:
    """赛季统计类"""
    def __init__(self, season):
        self.season = season
        self.players = {}
    def generate_simulated_data(self, num_players=10, games_per_player=20):
        """生成模拟数据"""
        np.random.seed(42)
        teams = ['湖人', '勇士', '火箭', '凯尔特人', '雄鹿', 
                '快船', '太阳', '掘金', '热火', '76人']
        for i in range(num_players):
            player_name = f"球员{i+1}"
            team = teams[i % len(teams)]
            player = PlayerStats(player_name, team)
            # 生成球员能力值
            ability = np.random.uniform(0.5, 1.0)
            for game in range(games_per_player):
                # 模拟单场比赛数据
                minutes = np.random.uniform(20, 40)
                points = int(ability * np.random.normal(20, 5) * minutes/30)
                rebounds = int(ability * np.random.normal(8, 3) * minutes/30)
                assists = int(ability * np.random.normal(6, 2))
                steals = int(ability * np.random.normal(2, 1))
                blocks = int(ability * np.random.normal(1, 0.5))
                turnovers = int(np.random.normal(3, 1))
                # 投篮数据
                fga = int(np.random.normal(18, 4))
                fgm = int(fga * (0.4 + ability * 0.1 + np.random.normal(0, 0.1)))
                fgm = max(0, min(fga, fgm))
                threepa = int(np.random.normal(7, 2))
                threepm = int(threepa * (0.3 + ability * 0.1))
                threepm = max(0, min(threepa, threepm))
                fta = int(np.random.normal(5, 2))
                ftm = int(fta * (0.75 + ability * 0.1))
                ftm = max(0, min(fta, ftm))
                game_stats = {
                    'game': game + 1,
                    'points': max(0, points),
                    'rebounds': max(0, rebounds),
                    'assists': max(0, assists),
                    'steals': max(0, steals),
                    'blocks': max(0, blocks),
                    'turnovers': max(0, turnovers),
                    'fga': fga, 'fgm': fgm,
                    '3pa': threepa, '3pm': threepm,
                    'fta': fta, 'ftm': ftm,
                    'minutes': round(minutes, 1)
                }
                player.add_game(game_stats)
            self.players[player_name] = player
        return self
    def get_player_comparison(self, player_names=None):
        """获取球员数据对比"""
        if player_names is None:
            player_names = list(self.players.keys())
        comparison_data = []
        for name in player_names:
            if name in self.players:
                player = self.players[name]
                stats = player.get_averages()
                stats['name'] = name
                stats['team'] = player.team
                stats['games'] = len(player.games)
                comparison_data.append(stats)
        return pd.DataFrame(comparison_data)

数据分析和可视化

class SeasonAnalyzer:
    """赛季分析器"""
    def __init__(self, season_stats):
        self.season_stats = season_stats
    def create_comparison_report(self, player_names):
        """生成对比报告"""
        df = self.season_stats.get_player_comparison(player_names)
        # 统计摘要
        summary = {
            '场均得分王': df.loc[df['points'].idxmax(), 'name'],
            '场均篮板王': df.loc[df['rebounds'].idxmax(), 'name'],
            '场均助攻王': df.loc[df['assists'].idxmax(), 'name'],
            '场均抢断王': df.loc[df['steals'].idxmax(), 'name'],
            '场均盖帽王': df.loc[df['blocks'].idxmax(), 'name'],
            '最高命中率': df.loc[df['fg_pct'].idxmax(), 'name'],
            '最高三分命中率': df.loc[df['3p_pct'].idxmax(), 'name']
        }
        return df, summary
    def plot_player_comparison(self, player_names, metrics=['points', 'rebounds', 'assists']):
        """绘制球员对比图表"""
        df = self.season_stats.get_player_comparison(player_names)
        # 创建雷达图
        if len(metrics) >= 3:
            self._create_radar_chart(df, metrics)
        # 创建柱状图
        self._create_bar_chart(df, metrics)
        # 创建热力图
        self._create_heatmap(df)
    def _create_radar_chart(self, df, metrics):
        """创建雷达图"""
        # 标准化数据用于雷达图
        normalized = df[metrics].copy()
        for col in metrics:
            if col in ['fg_pct', '3p_pct', 'ft_pct']:
                normalized[col] = normalized[col] / 100
            elif self.season_stats.players[df.iloc[0]['name']].total_stats[col if col != 'fg_pct' else 'fga'] > 0:
                max_val = normalized[col].max()
                if max_val > 0:
                    normalized[col] = normalized[col] / max_val
        # 雷达图
        angles = np.linspace(0, 2 * np.pi, len(metrics), endpoint=False).tolist()
        angles += angles[:1]
        fig, ax = plt.subplots(figsize=(10, 8), subplot_kw=dict(polar=True))
        for idx, player in df.iterrows():
            values = normalized.loc[idx].tolist()
            values += values[:1]
            ax.plot(angles, values, 'o-', linewidth=2, label=player['name'])
            ax.fill(angles, values, alpha=0.25)
        ax.set_xticks(angles[:-1])
        ax.set_xticklabels(metrics)
        ax.set_title(f'{self.season_stats.season}赛季球员数据对比 - 雷达图', fontsize=14)
        ax.legend(loc='upper right', bbox_to_anchor=(1.3, 1.0))
        plt.tight_layout()
        plt.show()
    def _create_bar_chart(self, df, metrics):
        """创建柱状图"""
        fig, axes = plt.subplots(1, len(metrics), figsize=(15, 6))
        for i, metric in enumerate(metrics):
            if len(metrics) > 1:
                ax = axes[i]
            else:
                ax = axes
            data = df.sort_values(metric, ascending=False)
            bars = ax.bar(data['name'], data[metric], alpha=0.8)
            # 添加数值标签
            for bar, value in zip(bars, data[metric]):
                ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.5,
                       f'{value:.1f}', ha='center', va='bottom', fontsize=8)
            ax.set_title(f'{metric}对比')
            ax.set_ylabel(metric)
            ax.set_xticklabels(data['name'], rotation=45)
        plt.suptitle(f'{self.season_stats.season}赛季数据对比', fontsize=14)
        plt.tight_layout()
        plt.show()
    def _create_heatmap(self, df):
        """创建热力图"""
        # 选择要显示的数据
        columns = ['points', 'rebounds', 'assists', 'steals', 'blocks', 'fg_pct', '3p_pct']
        columns = [col for col in columns if col in df.columns]
        plot_df = df.set_index('name')[columns]
        # 标准化每列以便可视化
        normalized = plot_df.copy()
        for col in columns:
            if col in ['fg_pct', '3p_pct']:
                normalized[col] = normalized[col] / 100
            else:
                normalized[col] = (normalized[col] - normalized[col].min()) / \
                                 (normalized[col].max() - normalized[col].min())
        plt.figure(figsize=(10, 8))
        sns.heatmap(normalized, annot=True, fmt='.3f', cmap='YlOrRd', 
                   cbar_kws={'label': '得分占比'})
        plt.title(f'{self.season_stats.season}赛季球员综合表现热力图')
        plt.tight_layout()
        plt.show()

主程序示例

def main():
    """主程序"""
    print("=" * 60)
    print("赛季累计数据统计与对比分析系统")
    print("=" * 60)
    # 生成 2023-24 赛季模拟数据
    season = SeasonStats("2023-24")
    season.generate_simulated_data(num_players=5, games_per_player=15)
    # 创建分析器
    analyzer = SeasonAnalyzer(season)
    # 获取球员对比数据
    player_names = list(season.players.keys())
    df, summary = analyzer.create_comparison_report(player_names)
    print("\n球员场均数据对比:")
    print(df[['name', 'team', 'games', 'points', 'rebounds', 'assists', 
              'steals', 'blocks', 'fg_pct', '3p_pct', 'ft_pct']].to_string(index=False))
    print("\n赛季亮点:")
    for title, player in summary.items():
        print(f"  {title}: {player}")
    # 生成统计图表
    print("\n生成可视化图表...")
    analyzer.plot_player_comparison(player_names, 
                                   metrics=['points', 'rebounds', 'assists'])
    # 输出详细统计报告
    print("\n详细赛季统计报告:")
    for player_name in player_names:
        player = season.players[player_name]
        stats = player.get_averages()
        print(f"\n{player_name} ({player.team}) - {len(player.games)}场比赛")
        print(f"  场均: {stats['points']}分, {stats['rebounds']}篮板, {stats['assists']}助攻")
        print(f"  命中率: 投篮{stats.get('fg_pct', 0)}%, 三分{stats.get('3p_pct', 0)}%, "
              f"罚球{stats.get('ft_pct', 0)}%")
        print(f"  效率值: {stats['points'] + stats['rebounds'] + stats['assists'] + "
              f"stats['steals'] + stats['blocks']}")
if __name__ == "__main__":
    main()

输出示例

运行该程序将产生:

  • 球员场均数据对比表格
  • 赛季亮点汇总
  • 雷达图、柱状图和热力图
  • 每位球员的详细统计报告

这个案例展示了如何:

  1. 使用面向对象思想设计数据模型
  2. 模拟生成赛季数据
  3. 计算场均数据和命中率
  4. 使用pandas进行数据对比分析
  5. 使用matplotlib和seaborn创建多种可视化图表
  6. 提供直观的数据对比和排名

您可以根据实际需求调整数据结构、添加更多统计指标(如正负值、效率值等),或增加更复杂的分析方法。

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