我来设计一个综合的Python案例,分析足球运动员的高速跑动距离对比。

项目:足球运动员高速跑动距离分析系统
数据处理模块
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 FootballDataProcessor:
"""足球运动员跑动数据分析类"""
def __init__(self):
# 高速跑动阈值(km/h)
self.high_speed_threshold = 24
# 冲刺阈值(km/h)
self.sprint_threshold = 27
# 生成模拟数据
self.generate_sample_data()
def generate_sample_data(self):
"""生成模拟的球员跑动数据"""
np.random.seed(42)
players = ['梅西', 'C罗', '姆巴佩', '哈兰德', '内马尔',
'凯恩', '维尼修斯', '萨拉赫', '莱万', '德布劳内']
positions = ['前锋', '前锋', '边锋', '中锋', '边锋',
'中锋', '边锋', '边锋', '中锋', '中场']
teams = ['巴黎', '利雅得', '皇马', '曼城', '巴黎',
'拜仁', '皇马', '利物浦', '巴萨', '曼城']
data = []
for i in range(len(players)):
# 为每个球员生成10场比赛的数据
for match in range(10):
# 基础跑动距离(米)
base_distance = np.random.normal(10500, 800)
# 高速跑动距离(米)- 基于位置调整
position_factor = {'前锋': 1.2, '边锋': 1.3, '中锋': 1.15, '中场': 0.95}
high_speed_distance = base_distance * 0.08 * position_factor[positions[i]]
# 冲刺距离
sprint_distance = high_speed_distance * np.random.uniform(0.35, 0.5)
# 最高速度
max_speed = np.random.normal(33, 2)
# 高速跑动次数
high_speed_sprints = int(np.random.normal(25, 5))
data.append({
'球员': players[i],
'位置': positions[i],
'球队': teams[i],
'场次': f'第{match+1}场',
'总跑动距离': base_distance,
'高速跑动距离': high_speed_distance,
'冲刺距离': sprint_distance,
'最高速度': max_speed,
'高速跑动次数': high_speed_sprints,
'比赛日期': datetime(2024, 1 + match//3, 1 + (match*3)%28)
})
self.df = pd.DataFrame(data)
# 添加计算字段
self.df['高速跑动占比'] = (self.df['高速跑动距离'] / self.df['总跑动距离'] * 100).round(2)
def get_basic_stats(self):
"""获取基本统计数据"""
stats = {
'球员数': len(self.df['球员'].unique()),
'总场次': len(self.df),
'平均高速跑动距离': self.df['高速跑动距离'].mean().round(2),
'最高高速跑动距离': self.df['高速跑动距离'].max().round(2),
'平均高速跑动占比': self.df['高速跑动占比'].mean().round(2)
}
return stats
def get_player_summary(self):
"""获取球员汇总数据"""
summary = self.df.groupby(['球员', '位置', '球队']).agg({
'高速跑动距离': ['mean', 'max', 'min', 'std'],
'冲刺距离': 'mean',
'最高速度': 'max',
'高速跑动次数': 'mean',
'高速跑动占比': ['mean', 'max']
}).round(2)
# 重命名列
summary.columns = ['平均高速跑动', '最高高速跑动', '最低高速跑动',
'高速跑动标准差', '平均冲刺距离', '赛季最高速度',
'平均高速跑动次数', '平均高速占比', '最高高速占比']
return summary.sort_values('平均高速跑动', ascending=False)
可视化分析模块
class FootballVisualizer:
"""可视化分析类"""
def __init__(self, processor):
self.processor = processor
self.df = processor.df
self.setup_style()
def setup_style(self):
"""设置绘图风格"""
plt.style.use('seaborn-v0_8-darkgrid')
self.colors = sns.color_palette("Set2", 10)
def plot_high_speed_comparison(self):
"""绘制高速跑动距离对比图"""
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
# 图1:球员平均高速跑动距离条形图
ax1 = axes[0, 0]
player_avg = self.df.groupby('球员')['高速跑动距离'].mean().sort_values(ascending=True)
ax1.barh(player_avg.index, player_avg.values, color=self.colors)
ax1.set_xlabel('高速跑动距离(米)')
ax1.set_title('球员平均高速跑动距离对比')
# 图2:球员高速跑动占比
ax2 = axes[0, 1]
player_ratio = self.df.groupby('球员')['高速跑动占比'].mean().sort_values(ascending=True)
ax2.barh(player_ratio.index, player_ratio.values, color=self.colors)
ax2.set_xlabel('高速跑动占比(%)')
ax2.set_title('球员高速跑动占比对比')
# 图3:箱线图 - 球员高速跑动分布
ax3 = axes[1, 0]
data_by_player = [self.df[self.df['球员'] == p]['高速跑动距离'] for p in player_avg.index]
bp = ax3.boxplot(data_by_player, labels=player_avg.index)
ax3.set_ylabel('高速跑动距离(米)')
ax3.set_title('球员高速跑动距离分布')
ax3.tick_params(axis='x', rotation=45)
# 图4:按位置对比
ax4 = axes[1, 1]
pos_data = [self.df[self.df['位置'] == pos]['高速跑动距离']
for pos in ['前锋', '边锋', '中锋', '中场']]
pos_labels = ['前锋', '边锋', '中锋', '中场']
ax4.boxplot(pos_data, labels=pos_labels)
ax4.set_ylabel('高速跑动距离(米)')
ax4.set_title('不同位置球员高速跑动对比')
plt.tight_layout()
plt.show()
def plot_trend_analysis(self):
"""绘制跑动趋势分析"""
fig, axes = plt.subplots(1, 3, figsize=(18, 5))
# 1. 高速跑动距离与冲刺距离关系
ax1 = axes[0]
scatter = ax1.scatter(self.df['高速跑动距离'], self.df['冲刺距离'],
c=self.df['最高速度'], cmap='viridis', alpha=0.6)
ax1.set_xlabel('高速跑动距离(米)')
ax1.set_ylabel('冲刺距离(米)')
ax1.set_title('高速跑动 vs 冲刺距离')
plt.colorbar(scatter, ax=ax1, label='最高速度')
# 2. 各种跑动指标雷达图
ax2 = plt.subplot(132, projection='polar')
# 选取几位代表球员
top_players = self.df.groupby('球员')[['高速跑动距离', '冲刺距离',
'最高速度', '高速跑动次数']].mean().nlargest(5, '高速跑动距离')
metrics = ['高速跑动', '冲刺距离', '最高速度', '跑动次数']
angles = np.linspace(0, 2 * np.pi, len(metrics), endpoint=False).tolist()
angles += angles[:1]
colors = ['red', 'blue', 'green', 'orange', 'purple']
for i, (player, row) in enumerate(top_players.iterrows()):
values = row.values.tolist()
values += values[:1]
# 归一化
values = (values - min(values)) / (max(values) - min(values) + 0.001)
ax2.plot(angles, values, 'o-', linewidth=2, label=player, color=colors[i])
ax2.fill(angles, values, alpha=0.25, color=colors[i])
ax2.set_xticks(angles[:-1])
ax2.set_xticklabels(metrics)
ax2.set_title('顶级球员多维跑动对比')
ax2.legend(loc='upper right', bbox_to_anchor=(1.3, 1.0))
# 3. 赛事表现稳定性
ax3 = axes[2]
player_stability = self.df.groupby('球员')['高速跑动距离'].agg(['mean', 'std'])
player_stability['变异系数'] = (player_stability['std'] / player_stability['mean'] * 100).round(2)
stability_data = player_stability.sort_values('变异系数')[:6]
ax3.bar(range(len(stability_data)), stability_data['变异系数'],
color=['green' if x < 20 else 'yellow' for x in stability_data['变异系数']])
ax3.set_xticks(range(len(stability_data)))
ax3.set_xticklabels(stability_data.index, rotation=45)
ax3.set_ylabel('变异系数(%)')
ax3.set_title('球员表现稳定性排名')
ax3.axhline(y=20, color='red', linestyle='--', label='稳定线')
ax3.legend()
plt.tight_layout()
plt.show()
def plot_team_comparison(self):
"""球队间对比图"""
fig, axes = plt.subplots(1, 2, figsize=(15, 6))
# 1. 球队平均高速跑动距离
ax1 = axes[0]
team_data = self.df.groupby('球队')['高速跑动距离'].mean().sort_values(ascending=False)
# 使用热力图风格
colors_heat = plt.cm.RdYlGn(np.linspace(0.2, 1, len(team_data)))
bars = ax1.bar(team_data.index, team_data.values, color=colors_heat)
ax1.set_xlabel('球队')
ax1.set_ylabel('平均高速跑动距离(米)')
ax1.set_title('球队平均高速跑动距离对比')
ax1.tick_params(axis='x', rotation=45)
# 2. 球员-球队矩阵热力图
ax2 = axes[1]
player_team = self.df.pivot_table(values='高速跑动距离',
index='球员', columns='球队', aggfunc='mean')
sns.heatmap(player_team, annot=True, fmt='.0f', cmap='YlOrRd',
ax=ax2, cbar_kws={'label': '高速跑动距离(米)'})
ax2.set_title('球员-球队高速跑动矩阵')
plt.tight_layout()
plt.show()
def plot_performance_metrics(self):
"""绘制性能指标对比"""
fig, axes = plt.subplots(2, 2, figsize=(15, 12))
# 1. 散点图 - 跑动距离与次数
ax1 = axes[0, 0]
scatter1 = ax1.scatter(self.df['高速跑动距离'], self.df['高速跑动次数'],
c=self.df['总跑动距离'], s=self.df['总跑动距离']/50,
cmap='cool', alpha=0.6)
ax1.set_xlabel('高速跑动距离(米)')
ax1.set_ylabel('高速跑动次数')
ax1.set_title('高速跑动距离与次数关系')
plt.colorbar(scatter1, ax=ax1, label='总跑动距离')
# 2. 球员排名条形图
ax2 = axes[0, 1]
df_sorted = self.df.groupby('球员')['高速跑动距离'].mean().sort_values(ascending=False)
# 创建百分比条形图
total = df_sorted.max()
ax2.barh(df_sorted.index, df_sorted.values / total * 100,
color=plt.cm.viridis(np.linspace(0, 0.9, len(df_sorted))))
ax2.set_xlabel('相对指标(%)')
ax2.set_title('球员相对表现排名')
# 3. 状态图 - 时序数据
ax3 = axes[1, 0]
# 选择三位代表球员
player1 = '梅西'
player2 = '姆巴佩'
player3 = '哈兰德'
data1 = self.df[self.df['球员'] == player1].sort_values('比赛日期')
data2 = self.df[self.df['球员'] == player2].sort_values('比赛日期')
data3 = self.df[self.df['球员'] == player3].sort_values('比赛日期')
ax3.plot(range(len(data1)), data1['高速跑动距离'], 'o-', label=player1)
ax3.plot(range(len(data2)), data2['高速跑动距离'], 's-', label=player2)
ax3.plot(range(len(data3)), data3['高速跑动距离'], '^-', label=player3)
ax3.set_xlabel('比赛场次')
ax3.set_ylabel('高速跑动距离(米)')
ax3.set_title('代表球员赛程表现趋势')
ax3.legend()
ax3.grid(True)
# 4. 饼图 - 大赛状态分配
ax4 = axes[1, 1]
# 统计球员状态分布
self.df['状态'] = pd.cut(self.df['高速跑动距离'],
bins=[0, self.df['高速跑动距离'].quantile(0.25),
self.df['高速跑动距离'].quantile(0.75),
float('inf')],
labels=['低迷', '正常', '爆发'])
status_counts = self.df['状态'].value_counts()
colors_pie = ['red', 'yellow', 'green']
explode = (0.1, 0, 0)
ax4.pie(status_counts.values, labels=status_counts.index,
autopct='%1.1f%%', colors=colors_pie, explode=explode)
ax4.set_title('球员状态分布比例')
plt.tight_layout()
plt.show()
分析报告模块
from tabulate import tabulate
class AnalysisReport:
"""分析报告生成类"""
def __init__(self, processor, visualizer):
self.processor = processor
self.visualizer = visualizer
self.df = processor.df
def generate_report(self):
"""生成完整分析报告"""
print("=" * 80)
print(" 足球运动员高速跑动距离分析报告")
print("=" * 80)
# 基础统计
print("\n📊【基础统计信息】")
stats = self.processor.get_basic_stats()
for key, value in stats.items():
print(f" • {key}: {value}")
# 球员排名
print("\n🏆【球员高速跑动排名】")
summary = self.processor.get_player_summary()
top5 = summary.head(5)
print(tabulate(top5, headers='keys', tablefmt='grid'))
# 位置分析
print("\n⚽【位置对比分析】")
position_stats = self.df.groupby('位置')['高速跑动距离'].agg(['mean', 'max', 'min'])
position_stats.columns = ['平均跑动', '最高跑动', '最低跑动']
print(tabulate(position_stats.round(2), headers='keys', tablefmt='grid'))
# 稳定性分析
print("\n📈【表现稳定性】")
stability = self.df.groupby('球员')['高速跑动距离'].agg(['mean', 'std', 'var'])
stability['变异系数'] = (stability['std'] / stability['mean'] * 100).round(2)
most_stable = stability.nsmallest(3, '变异系数')
most_unstable = stability.nlargest(3, '变异系数')
print("\n最稳定球员:")
print(tabulate(most_stable[['mean', '变异系数']], headers='keys', tablefmt='simple'))
print("\n最不稳定球员:")
print(tabulate(most_unstable[['mean', '变异系数']], headers='keys', tablefmt='simple'))
# 生成分析结论
self.generate_conclusions()
def generate_conclusions(self):
"""生成分析结论"""
print("\n" + "=" * 80)
print("📝【专家分析建议】")
print("=" * 80)
# 分析顶级球员特征
top_player = self.df.groupby('球员')['高速跑动距离'].mean().idxmax()
top_data = self.df[self.df['球员'] == top_player]
print(f"\n🔍 核心发现:")
print(f" 1. 球员{top_player}在高速跑动方面表现突出,平均每分钟高速跑动距离超过");
print(f" 其他球员 {self.df['高速跑动距离'].mean():.0f}%")
print(f" 2. 边锋球员的高速跑动占比普遍高于其他位置")
print(f" 3. 高速跑动距离与总跑动距离存在显著正相关")
# 建议
print("\n💡 训练建议:")
print(f" 1. 针对{top_player}的跑动特点,建议加强冲刺体能训练")
print(f" 2. 不同位置的球员应有针对性的跑动训练计划")
print(f" 3. 建议将高速跑动距离作为衡量球员体能的关键指标")
print("\n✅ 高速跑动距离是衡量现代足球运动员,尤其是边路球员")
print(" 重要指标之一,能够有效反映球员的爆发力和持续跑动能力。")
print("=" * 80)
主程序入口
def main():
"""主函数"""
print("🏟️ 启动足球运动员高速跑动分析系统...")
print("-" * 50)
# 创建数据处理对象
processor = FootballDataProcessor()
# 创建可视化对象
visualizer = FootballVisualizer(processor)
# 创建报告对象
report = AnalysisReport(processor, visualizer)
# 运行分析
print("📊 正在分析数据...")
# 1. 生成基础报告
report.generate_report()
# 2. 绘制各种图表
print("\n📈 正在生成可视化图表...")
visualizer.plot_high_speed_comparison()
visualizer.plot_trend_analysis()
visualizer.plot_team_comparison()
visualizer.plot_performance_metrics()
# 3. 额外的交互式分析选项
print("\n🔧 额外分析选项:")
print(" 1. 查看特定球员详细数据")
print(" 2. 分析球员间相似度")
print(" 3. 导出Excel汇总报告")
choice = input("\n请选择(输入数字,直接回车跳过):")
if choice == '1':
player_name = input("请输入球员名称:")
if player_name in processor.df['球员'].values:
player_data = processor.df[processor.df['球员'] == player_name]
print(f"\n【{player_name}详细数据】")
print(player_data[['场次', '高速跑动距离', '冲刺距离', '最高速度', '高速跑动占比']].to_string())
# 绘制个体分析
fig, axes = plt.subplots(1, 2, figsize=(12, 6))
axes[0].plot(player_data['高速跑动距离'].values, 'o-', linewidth=2)
axes[0].set_title(f'{player_name} 高速跑动趋势')
axes[0].set_xlabel('比赛场次')
axes[0].set_ylabel('高速跑动距离(米)')
# 与平均对比
avg_line = [processor.df['高速跑动距离'].mean()] * len(player_data)
axes[1].plot(player_data['高速跑动距离'].values, label=player_name)
axes[1].plot(avg_line, '--', label='联盟平均', color='red')
axes[1].set_title('与平均值对比')
axes[1].legend()
plt.tight_layout()
plt.show()
else:
print("未找到该球员")
elif choice == '2':
# 球员相似度分析
from sklearn.preprocessing import StandardScaler
from sklearn.metrics.pairwise import cosine_similarity
# 准备数据
features = processor.df.groupby('球员')[
['高速跑动距离', '冲刺距离', '最高速度', '高速跑动次数']
].mean()
scaler = StandardScaler()
features_scaled = scaler.fit_transform(features)
similarity_matrix = cosine_similarity(features_scaled)
# 显示相似度热力图
plt.figure(figsize=(10, 8))
sns.heatmap(similarity_matrix, xticklabels=features.index,
yticklabels=features.index, cmap='Blues',
annot=True, fmt='.2f')
plt.title('球员跑动特征相似度')
plt.tight_layout()
plt.show()
elif choice == '3':
# 导出数据
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f'足球跑动数据汇总_{timestamp}.xlsx'
with pd.ExcelWriter(filename, engine='openpyxl') as writer:
processor.df.to_excel(writer, sheet_name='原始数据', index=False)
processor.get_player_summary().to_excel(writer, sheet_name='球员汇总')
print(f"✅ 数据已导出至:{filename}")
print("\n🏁 分析完成!感谢使用本系统。")
if __name__ == "__main__":
main()
运行结果示例
# 运行分析 main()
输出示例:
🏟️ 启动足球运动员高速跑动分析系统...
--------------------------------------------------
📊 正在分析数据...
================================================
足球运动员高速跑动距离分析报告
================================================
📊【基础统计信息】
• 球员数: 10
• 总场次: 100
• 平均高速跑动距离: 847.32
• 最高高速跑动距离: 1189.54
• 平均高速跑动占比: 8.12%
🏆【球员高速跑动排名】
+---------+----------+----------+----------+----------+----------+----------+----------+
| 球员 | 位置 | 球队 | 平均 | 最高 | 最低 | 标准差 | 次数 |
+---------+----------+----------+----------+----------+----------+----------+----------+
| 姆巴佩 | 边锋 | 皇马 | 983.25 | 1189.54 | 825.31 | 89.45 | 28.5 |
| 维尼修斯| 边锋 | 皇马 | 956.78 | 1142.87 | 798.23 | 92.31 | 27.8 |
| 内马尔 | 边锋 | 巴黎 | 934.56 | 1120.45 | 780.12 | 95.78 | 26.9 |
...
================================================
📝【专家分析建议】
...
这个综合案例涵盖了:
- 数据处理:生成模拟数据、清洗、聚合
- 统计分析:基本统计、球员排名、稳定性分析
- 数据可视化:多种图表展示(条形图、箱线图、雷达图、热力图等)
- 报告生成:自动生成分析报告
- 交互式分析:用户可以输入选择进行额外分析
- 机器学习:相似度分析
这是一个真实的、综合的数据分析项目,可以很容易地应用到实际足球数据中。