本文目录导读:

我来为你设计一个完整的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个图表:
- 伤病表现对比图:柱状图对比有无伤病时的数据
- 伤病类型饼图:各类伤病占比
- 位置伤病分布:不同球员位置的伤病次数
- 伤停累计影响:伤停场次与胜率的关系曲线
使用方法
# 运行完整分析 analyzer = InjuryImpactAnalyzer() analyzer.generate_sample_data() analyzer.basic_statistics() analyzer.visualization() # 导出Excel报告 analyzer.export_report()
这个系统能够帮助球队管理层、教练组了解伤病对球队成绩的具体影响,从而更好地进行球员管理和训练安排,你可以调整参数来分析不同场景,或者接入真实比赛数据进行深入分析。