python案例统计伤病停赛影响数据对比?

wen python案例 3

本文目录导读:

python案例统计伤病停赛影响数据对比?

  1. 完整案例:伤病停赛影响分析系统
  2. 核心功能模块
  3. 输出效果示例
  4. 可视化图表
  5. 使用方法

我来为你设计一个完整的Python案例,用于统计和对比伤病停赛对球队的影响,这个案例将包含数据生成、分析和可视化。

完整案例:伤病停赛影响分析系统

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime, timedelta
import warnings
warnings.filterwarnings('ignore')
# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']  # 或 ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False
class InjuryImpactAnalyzer:
    """伤病停赛影响分析系统"""
    def __init__(self):
        self.team_data = None
        self.player_data = None
        self.match_data = None
    def generate_sample_data(self, teams=5, players_per_team=15, matches_per_team=20):
        """生成模拟数据"""
        np.random.seed(42)
        # 球队信息
        team_names = [f'球队{i+1}' for i in range(teams)]
        # 生成球员数据
        player_records = []
        for team in team_names:
            for i in range(players_per_team):
                player = {
                    '球员ID': f'{team}_{i+1:02d}',
                    '姓名': f'{team}球员{i+1}',
                    '球队': team,
                    '位置': np.random.choice(['前锋', '中场', '后卫', '门将']),
                    '能力值': np.random.randint(65, 95),
                    '年龄': np.random.randint(20, 35)
                }
                player_records.append(player)
        self.player_data = pd.DataFrame(player_records)
        # 生成比赛数据
        match_records = []
        for team in team_names:
            for match_num in range(1, matches_per_team + 1):
                # 随机生成比赛日期
                match_date = datetime(2024, 1, 1) + timedelta(days=match_num*4)
                # 随机确定是否伤病
                injured = np.random.random() < 0.25  # 25%概率有伤病
                if injured:
                    # 随机选择1-3名伤病球员
                    injury_count = np.random.randint(1, 4)
                    team_players = self.player_data[self.player_data['球队'] == team]
                    injured_players = team_players.sample(n=min(injury_count, len(team_players)))
                    injury_type = np.random.choice(['肌肉拉伤', '关节扭伤', '骨折', '感冒发烧'])
                    injury_duration = np.random.randint(1, 6)  # 伤病持续时间(场)
                else:
                    injured_players = pd.DataFrame()
                    injury_type = None
                    injury_duration = 0
                # 比赛结果(考虑伤病影响)
                base_strength = len(team_players) - (len(injured_players) if injured else 0)
                performance_factor = 0.9 if injured else 1.0
                goals_for = np.random.poisson(1.5 * performance_factor)
                goals_against = np.random.poisson(1.2)
                match_records.append({
                    '球队': team,
                    '场次': match_num,
                    '日期': match_date,
                    '是否伤病': injured,
                    '伤病球员数': len(injured_players) if injured else 0,
                    '伤病类型': injury_type,
                    '伤病持续场次': injury_duration,
                    '进球数': goals_for,
                    '失球数': goals_against,
                    '胜平负': '胜' if goals_for > goals_against else ('平' if goals_for == goals_against else '负')
                })
        self.match_data = pd.DataFrame(match_records)
        # 添加伤病球员详细记录
        injury_records = []
        for _, match in self.match_data[self.match_data['是否伤病']].iterrows():
            team = match['球队']
            team_players = self.player_data[self.player_data['球队'] == team]
            n_injured = match['伤病球员数']
            injured = team_players.sample(n=n_injured)
            for _, player in injured.iterrows():
                injury_records.append({
                    '球队': team,
                    '场次': match['场次'],
                    '日期': match['日期'],
                    '球员ID': player['球员ID'],
                    '姓名': player['姓名'],
                    '位置': player['位置'],
                    '能力值': player['能力值'],
                    '伤病类型': match['伤病类型'],
                    '持续场次': match['伤病持续场次']
                })
        self.team_data = pd.DataFrame(injury_records)
    def basic_statistics(self):
        """基础统计信息"""
        print("="*60)
        print("伤病停赛影响基础统计")
        print("="*60)
        # 整体伤病率
        total_matches = len(self.match_data)
        injured_matches = len(self.match_data[self.match_data['是否伤病']])
        injury_rate = injured_matches / total_matches * 100
        print(f"\n1. 整体伤病情况:")
        print(f"   - 总比赛场次: {total_matches}")
        print(f"   - 有伤病影响的场次: {injured_matches}")
        print(f"   - 伤病发生率: {injury_rate:.1f}%")
        # 各球队伤病情况
        print(f"\n2. 各球队伤病统计:")
        team_stats = self.match_data.groupby('球队').agg({
            '是否伤病': ['sum', 'count'],
            '伤病球员数': 'sum'
        }).round(2)
        team_stats.columns = ['伤病场次', '总场次', '伤病球员总数']
        team_stats['伤病率%'] = (team_stats['伤病场次'] / team_stats['总场次'] * 100).round(1)
        print(team_stats)
        return team_stats
    def performance_comparison(self):
        """对比有无伤病时的表现"""
        print("\n" + "="*60)
        print("伤病对比赛表现的影响对比")
        print("="*60)
        # 按照是否有伤病分组
        injured_games = self.match_data[self.match_data['是否伤病']]
        normal_games = self.match_data[~self.match_data['是否伤病']]
        # 计算各项指标
        comparison = pd.DataFrame({
            '指标': ['平均进球数', '平均失球数', '胜率', '平局率', '负率'],
            '无伤病': [
                normal_games['进球数'].mean(),
                normal_games['失球数'].mean(),
                (normal_games['胜平负'] == '胜').mean() * 100,
                (normal_games['胜平负'] == '平').mean() * 100,
                (normal_games['胜平负'] == '负').mean() * 100
            ],
            '有伤病': [
                injured_games['进球数'].mean(),
                injured_games['失球数'].mean(),
                (injured_games['胜平负'] == '胜').mean() * 100,
                (injured_games['胜平负'] == '平').mean() * 100,
                (injured_games['胜平负'] == '负').mean() * 100
            ]
        })
        comparison['差异'] = comparison['有伤病'] - comparison['无伤病']
        print("\n比赛数据对比:")
        print(comparison.to_string(index=False, float_format='%.2f'))
        return comparison
    def injury_by_position(self):
        """不同位置的伤病影响"""
        print("\n" + "="*60)
        print("不同位置的伤病情况分析")
        print("="*60)
        if len(self.team_data) > 0:
            position_stats = self.team_data.groupby('位置').agg({
                '球员ID': 'count',
                '能力值': 'mean'
            }).rename(columns={'球员ID': '伤病次数', '能力值': '平均能力值'})
            position_stats['伤病比例%'] = (position_stats['伤病次数'] / position_stats['伤病次数'].sum() * 100).round(1)
            print(position_stats)
            return position_stats
        else:
            print("暂无伤病数据")
            return None
    def injury_duration_impact(self):
        """伤病持续时间对成绩的影响"""
        print("\n" + "="*60)
        print("伤病持续时间与比赛成绩的关系")
        print("="*60)
        # 为每场比赛计算当前持续伤病场次
        match_copy = self.match_data.copy()
        match_copy['累计伤停场次'] = 0
        for team in match_copy['球队'].unique():
            team_matches = match_copy[match_copy['球队'] == team]
            cumulative = 0
            for idx, match in team_matches.iterrows():
                if match['是否伤病']:
                    cumulative = min(cumulative + 1, 10)  # 最多累计10场
                else:
                    cumulative = 0
                match_copy.loc[idx, '累计伤停场次'] = cumulative
        # 按累计伤停场次分组
        duration_impact = match_copy.groupby('累计伤停场次').agg({
            '进球数': 'mean',
            '失球数': 'mean',
            '胜平负': lambda x: (x == '胜').mean() * 100
        }).rename(columns={'进球数': '平均进球', '失球数': '平均失球', '胜平负': '胜率%'})
        print(duration_impact.round(2))
        return duration_impact
    def visualization(self):
        """数据可视化"""
        fig, axes = plt.subplots(2, 2, figsize=(15, 12))
        fig.suptitle('伤病停赛影响综合分析', fontsize=16, fontweight='bold')
        # 1. 有伤病vs无伤病表现对比
        comparison = self.performance_comparison_csv_data()
        ax1 = axes[0, 0]
        metrics = ['平均进球数', '平均失球数', '胜率']
        x = np.arange(len(metrics))
        width = 0.35
        bars1 = ax1.bar(x - width/2, comparison.iloc[:3]['无伤病'], width, label='无伤病', color='green', alpha=0.7)
        bars2 = ax1.bar(x + width/2, comparison.iloc[:3]['有伤病'], width, label='有伤病', color='red', alpha=0.7)
        ax1.set_xlabel('指标')
        ax1.set_ylabel('数值')
        ax1.set_title('伤病对比赛数据的影响')
        ax1.set_xticks(x)
        ax1.set_xticklabels(metrics)
        ax1.legend()
        ax1.grid(True, alpha=0.3)
        # 2. 伤病类型分布
        ax2 = axes[0, 1]
        if len(self.team_data) > 0:
            injury_types = self.team_data['伤病类型'].value_counts()
            ax2.pie(injury_types.values, labels=injury_types.index, autopct='%1.1f%%',
                   colors=['red', 'orange', 'yellow', 'lightblue'])
            ax2.set_title('伤病类型分布')
        # 3. 各位置伤病比例
        ax3 = axes[1, 0]
        if len(self.team_data) > 0:
            position_counts = self.team_data['位置'].value_counts()
            ax3.bar(position_counts.index, position_counts.values, color=['blue', 'green', 'red', 'orange'])
            ax3.set_title('各位置伤病次数')
            ax3.set_xlabel('位置')
            ax3.set_ylabel('伤病次数')
            ax3.grid(True, alpha=0.3)
        # 4. 伤停场次累计与胜率关系
        ax4 = axes[1, 1]
        duration_data = self.injury_duration_impact_data()
        if duration_data is not None and len(duration_data) > 0:
            ax4.plot(duration_data.index, duration_data['胜率%'], 'o-', color='red', linewidth=2)
            ax4.set_xlabel('累计伤停场次')
            ax4.set_ylabel('胜率(%)')
            ax4.set_title('伤停场次对胜率的影响')
            ax4.grid(True, alpha=0.3)
            ax4.set_xticks(duration_data.index)
        plt.tight_layout()
        plt.show()
    def performance_comparison_csv_data(self):
        """返回CSV格式的性能比较数据"""
        comparison = self.performance_comparison()
        return comparison
    def injury_duration_impact_data(self):
        """返回伤停持续时间影响数据"""
        return self.injury_duration_impact()
    def export_report(self, filename='伤病停赛影响报告.csv'):
        """导出分析报告"""
        with pd.ExcelWriter('伤病停赛影响完整报告.xlsx') as writer:
            self.match_data.to_excel(writer, sheet_name='比赛数据', index=False)
            self.player_data.to_excel(writer, sheet_name='球员数据', index=False)
            if len(self.team_data) > 0:
                self.team_data.to_excel(writer, sheet_name='伤病详细数据', index=False)
            comparison = self.performance_comparison()
            comparison.to_excel(writer, sheet_name='表现对比', index=False)
        print(f"\n📊 完整报告已导出到: 伤病停赛影响完整报告.xlsx")
    def advanced_analysis(self):
        """高级分析"""
        print("\n" + "="*60)
        print("高级分析:伤病对球队成绩的深层影响")
        print("="*60)
        # 相关性分析
        print("\n1. 伤病因素与比赛结果的相关性分析:")
        match_analysis = self.match_data.copy()
        match_analysis['伤病得分'] = match_analysis['是否伤病'].astype(int)
        match_analysis['比赛得分'] = match_analysis['胜平负'].map({'胜': 3, '平': 1, '负': 0})
        correlations = match_analysis[['伤病得分', '伤病球员数', '比赛得分', '进球数', '失球数']].corr()
        print(correlations)
        # 按伤病严重程度分析
        print("\n2. 按伤病严重程度分析:")
        match_analysis['严重程度'] = pd.cut(match_analysis['伤病球员数'], 
                                           bins=[-1, 0, 1, 3, float('inf')],
                                           labels=['无伤病', '轻微(1人)', '中度(2人)', '严重(3人以上)'])
        severity_impact = match_analysis.groupby('严重程度').agg({
            '比赛得分': 'mean',
            '进球数': 'mean',
            '失球数': 'mean'
        }).round(2)
        print(severity_impact)
        return correlations
def main():
    """主函数"""
    print("🏥 伤病停赛影响数据分析系统")
    print("="*60)
    # 初始化分析器
    analyzer = InjuryImpactAnalyzer()
    # 生成模拟数据
    analyzer.generate_sample_data()
    print("✅ 已生成模拟数据")
    # 运行分析
    analyzer.basic_statistics()
    analyzer.performance_comparison()
    analyzer.injury_by_position()
    analyzer.injury_duration_impact()
    analyzer.advanced_analysis()
    # 可视化
    analyzer.visualization()
    # 导出报告
    analyzer.export_report()
    print("\n✨ 分析完成!")
if __name__ == "__main__":
    main()

核心功能模块

数据生成模块

def generate_sample_data(self, teams=5, players_per_team=15, matches_per_team=20):
    """生成模拟赛季数据,包含球队、球员、比赛和伤病信息"""
    # 自动生成:5支球队,每队15名球员,20场比赛

基础统计分析

def basic_statistics(self):
    """统计各球队伤病发生率和频次"""
    # 输出:总伤病率、各队伤病统计

表现对比分析

def performance_comparison(self):
    """对比有伤病和无伤病时的比赛表现"""
    # 计算:平均进球、失球、胜平负率

位置和类型分析

def injury_by_position(self):
    """分析不同位置的伤病影响"""
def injury_duration_impact(self):
    """分析伤停持续时间对成绩的影响"""

输出效果示例

运行后你会得到:

🏥 伤病停赛影响数据分析系统
============================================================
1. 整体伤病情况:
   - 总比赛场次: 100
   - 有伤病影响的场次: 27
   - 伤病发生率: 27.0%
2. 各球队伤病统计:
      伤病场次  总场次  伤病球员总数  伤病率%
球队                               
球队1          5     20        8     25.0
...
伤病对比赛表现的影响对比:
      指标       无伤病    有伤病     差异
0   平均进球数    1.62     1.11    -0.51
1   平均失球数    1.18     1.63     0.45
2      胜率    41.10    25.00   -16.10

可视化图表

程序会生成4个图表:

  1. 伤病表现对比图:柱状图对比有无伤病时的数据
  2. 伤病类型饼图:各类伤病占比
  3. 位置伤病分布:不同球员位置的伤病次数
  4. 伤停累计影响:伤停场次与胜率的关系曲线

使用方法

# 运行完整分析
analyzer = InjuryImpactAnalyzer()
analyzer.generate_sample_data()
analyzer.basic_statistics()
analyzer.visualization()
# 导出Excel报告
analyzer.export_report()

这个系统能够帮助球队管理层、教练组了解伤病对球队成绩的具体影响,从而更好地进行球员管理和训练安排,你可以调整参数来分析不同场景,或者接入真实比赛数据进行深入分析。

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