我来为您设计一个综合Python案例,分析足球比赛中不同球员的高速跑动距离对比。

项目:足球运动员高速跑动分析系统
数据生成模块
import numpy as np
import pandas as pd
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']
plt.rcParams['axes.unicode_minus'] = False
class PlayerPerformanceAnalyzer:
"""足球运动员跑动性能分析器"""
def __init__(self):
self.players_data = None
self.speed_threshold = 25 # 高速跑动阈值 (km/h)
self.sprint_threshold = 30 # 冲刺速度阈值 (km/h)
def generate_player_data(self, num_players=8, matches_per_player=10):
"""生成模拟球员跑动数据"""
players = []
positions = ['前锋', '中场', '后卫', '边锋']
# 各位置速度特征(平均值,标准差)
position_speeds = {
'前锋': (27.5, 2.0),
'中场': (24.5, 1.8),
'后卫': (23.0, 1.5),
'边锋': (28.0, 2.2)
}
for player_id in range(num_players):
position = positions[player_id % len(positions)]
for match_num in range(matches_per_player):
# 生成比赛时间戳(90分钟比赛)
match_duration = 90
timestamp = np.arange(0, match_duration, 0.1)
# 根据位置生成基础速度
base_speed_mean, base_speed_std = position_speeds[position]
# 模拟跑动速度变化(加入一些随机性和比赛节奏变化)
speed_noise = np.random.normal(base_speed_mean, base_speed_std, len(timestamp))
match_rhythm = np.sin(timestamp/10) * 5 # 模拟比赛节奏
fatigue_factor = np.linspace(1, 0.85, len(timestamp)) # 模拟疲劳
speeds = np.abs(speed_noise + match_rhythm) * fatigue_factor
speeds = np.clip(speeds, 4, 38) # 限制在合理范围
# 计算距离(km/h * 时间(h))
distance_per_sample = speeds * (0.1/3600) # 每个采样点的距离(km)
# 累加生成球员比赛数据
player_data = {
'player_id': f'Player_{player_id+1:02d}',
'player_name': f'球员{player_id+1:02d}',
'position': position,
'match_id': f'Match_{match_num+1:02d}',
'total_distance': np.sum(distance_per_sample), # 总距离(km)
'avg_speed': np.mean(speeds), # 平均速度(km/h)
'max_speed': np.max(speeds), # 最大速度(km/h)
'high_speed_distance': np.sum(distance_per_sample[speeds >= self.speed_threshold]), # 高速跑动距离
'sprint_distance': np.sum(distance_per_sample[speeds >= self.sprint_threshold]), # 冲刺距离
'high_speed_runs': np.sum(speeds >= self.speed_threshold), # 高速跑动次数
'sprint_runs': np.sum(speeds >= self.sprint_threshold), # 冲刺次数
'high_speed_duration': np.sum(speeds >= self.speed_threshold) * 0.1/3600, # 高速跑动时间(h)
'speed_percentiles': np.percentile(speeds, [25, 50, 75, 90]) # 速度分位数
}
players.append(player_data)
self.players_data = pd.DataFrame(players)
return self.players_data
def analyze_high_speed_performance(self):
"""分析高速度跑动表现"""
if self.players_data is None:
raise ValueError("请先加载或生成数据")
# 按球员分组汇总
player_summary = self.players_data.groupby(['player_id', 'player_name', 'position']).agg({
'high_speed_distance': 'mean', # 平均每场高速跑动距离
'sprint_distance': 'mean',
'high_speed_runs': 'mean',
'sprint_runs': 'mean',
'max_speed': 'max',
'total_distance': 'mean',
'high_speed_duration': 'mean'
}).round(2)
player_summary.columns = ['场均高速跑动(km)', '场均冲刺距离(km)',
'高速跑动次数', '冲刺次数',
'最大速度(km/h)', '总跑动距离(km)',
'高速跑动时间(min)']
# 添加高速跑动占比
player_summary['高速跑动占比(%)'] = (player_summary['场均高速跑动(km)'] /
player_summary['总跑动距离(km)'] * 100).round(2)
# 计算综合得分
player_summary['综合得分'] = (player_summary['场均高速跑动(km)'] * 0.4 +
player_summary['冲刺次数'] * 0.3 +
player_summary['最大速度(km/h)'] * 0.3).round(2)
return player_summary.sort_values('综合得分', ascending=False)
可视化模块
class PerformanceVisualizer:
"""性能可视化类"""
@staticmethod
def plot_high_speed_comparison(data, title="球员高速跑动距离对比"):
"""绘制高速跑动距离对比图"""
fig, axes = plt.subplots(2, 2, figsize=(16, 12))
# 1. 高速跑动距离柱状图
ax1 = axes[0, 0]
bars = ax1.bar(data.index, data['场均高速跑动(km)'],
color=plt.cm.RdYlGn(np.linspace(0.2, 0.8, len(data))))
ax1.set_title('场均高速跑动距离对比', fontsize=12, fontweight='bold')
ax1.set_xlabel('球员')
ax1.set_ylabel('距离 (km)')
ax1.set_xticklabels(data.index, rotation=45)
for bar, val in zip(bars, data['场均高速跑动(km)']):
ax1.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.05,
f'{val:.2f}', ha='center', va='bottom', fontsize=9)
# 2. 高速跑动占比饼图
ax2 = axes[0, 1]
explode = [0.03] * len(data[:5]) # 突出前5名
ax2.pie(data['高速跑动占比(%)'][:5],
labels=data.index[:5],
autopct='%1.1f%%',
explode=explode[:len(data[:5])],
startangle=90)
ax2.set_title('前5名球员高速跑动占比', fontsize=12, fontweight='bold')
# 3. 散点图:总距离 vs 高速跑动距离
ax3 = axes[1, 0]
scatter = ax3.scatter(data['总跑动距离(km)'],
data['场均高速跑动(km)'],
s=data['综合得分']*10, # 点大小随得分变化
c=range(len(data)),
cmap='viridis',
alpha=0.6)
ax3.set_xlabel('总跑动距离 (km)')
ax3.set_ylabel('高速跑动距离 (km)')
ax3.set_title('总距离与高速跑动距离关系', fontsize=12, fontweight='bold')
ax3.set_zorder(2)
# 为散点添加球员标签
for idx, label in enumerate(data.index):
ax3.annotate(label,
(data['总跑动距离(km)'].iloc[idx],
data['场均高速跑动(km)'].iloc[idx]),
textcoords="offset points",
xytext=(5,5),
fontsize=8)
# 4. 综合得分排名条形图
ax4 = axes[1, 1]
colors = plt.cm.hot_r(np.linspace(0.2, 1, len(data)))
bars = ax4.barh(data.index, data['综合得分'], color=colors)
ax4.set_xlabel('综合得分')
ax4.set_title('综合得分排名', fontsize=12, fontweight='bold')
ax4.invert_yaxis()
# 在条形上添加数值
for bar, val in zip(bars, data['综合得分']):
ax4.text(bar.get_width() + 0.5, bar.get_y() + bar.get_height()/2,
f'{val:.1f}', va='center', fontsize=9)
plt.suptitle(title, fontsize=16, fontweight='bold')
plt.tight_layout()
plt.show()
@staticmethod
def plot_radar_comparison(data, top_n=4, players=None):
"""雷达图对比多个球员的多维度表现"""
if players is None:
players = data.index[:top_n]
# 选择雷达图指标
metrics = ['场均高速跑动(km)', '高速跑动次数', '冲刺次数',
'最大速度(km/h)', '高速跑动占比(%)', '综合得分']
# 数据归一化
data_selected = data.loc[players, metrics]
data_normalized = (data_selected - data_selected.min()) / (data_selected.max() - data_selected.min())
# 设定雷达图角度
angles = np.linspace(0, 2 * np.pi, len(metrics), endpoint=False).tolist()
angles += angles[:1] # 使图形闭合
fig, ax = plt.subplots(figsize=(10, 10), subplot_kw=dict(polar=True))
colors = ['#e74c3c', '#3498db', '#2ecc71', '#f39c12']
for idx, player in enumerate(players):
values = data_normalized.loc[player].values.tolist()
values += values[:1]
ax.plot(angles, values, 'o-', linewidth=2,
label=player, color=colors[idx % len(colors)])
ax.fill(angles, values, alpha=0.15, color=colors[idx % len(colors)])
ax.set_xticks(angles[:-1])
ax.set_xticklabels(metrics)
ax.set_ylim(0, 1)
ax.set_title('球员多维性能对比雷达图', fontsize=15, fontweight='bold', pad=20)
ax.grid(True)
ax.legend(loc='upper right', bbox_to_anchor=(1.3, 1.0))
plt.tight_layout()
plt.show()
@staticmethod
def plot_position_comparison(data):
"""按位置对比分析"""
# 按位置分组统计
position_data = data.groupby('position').agg({
'场均高速跑动(km)': 'mean',
'冲刺次数': 'mean',
'最大速度(km/h)': 'mean',
'总跑动距离(km)': 'mean'
}).round(2)
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
metrics_mapping = {
'场均高速跑动(km)': ('平均高速跑动距离', 'km'),
'冲刺次数': ('平均冲刺次数', '次'),
'最大速度(km/h)': ('平均最大速度', 'km/h'),
'总跑动距离(km)': ('平均总跑动距离', 'km')
}
for idx, (metric, (title, unit)) in enumerate(metrics_mapping.items()):
ax = axes[idx // 2, idx % 2]
positions = position_data.index.tolist()
values = position_data[metric].tolist()
bars = ax.bar(positions, values,
color=['#e74c3c', '#3498db', '#2ecc71', '#f39c12'],
edgecolor='black', linewidth=0.5)
ax.set_title(title, fontsize=11, fontweight='bold')
ax.set_ylabel(f'平均值 ({unit})')
# 添加数值标签
for bar, val in zip(bars, values):
ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.1,
f'{val:.2f}', ha='center', va='bottom', fontsize=9)
plt.suptitle('不同位置的跑动性能对比', fontsize=14, fontweight='bold')
plt.tight_layout()
plt.show()
统计分析模块
class StatisticalAnalyzer:
"""统计分析类"""
@staticmethod
def calculate_correlations(data):
"""计算相关性矩阵"""
numeric_cols = ['场均高速跑动(km)', '冲刺距离(km)', '高速跑动次数',
'冲刺次数', '最大速度(km/h)', '总跑动距离(km)', '综合得分']
# 重命名列
data_renamed = data.copy()
if '场均冲刺距离(km)' in data.columns:
data_renamed.rename(columns={'场均冲刺距离(km)': '冲刺距离(km)'}, inplace=True)
corr_data = data_renamed[[col for col in numeric_cols if col in data_renamed.columns]]
corr_matrix = corr_data.corr()
return corr_matrix
@staticmethod
def pair_plot_analysis(data):
"""成对散点图分析"""
cols = ['场均高速跑动(km)', '冲刺次数', '最大速度(km/h)', '综合得分']
# 创建成对关系图
g = sns.PairGrid(data[cols if set(cols).issubset(data.columns) else
[col for col in cols if col in data.columns]])
g.map_upper(sns.scatterplot, color='crimson')
g.map_lower(sns.kdeplot, cmap='Reds')
g.map_diag(sns.histplot, kde=True, color='darkblue')
g.fig.suptitle('球员性能指标成对分析', y=1.02, fontsize=14, fontweight='bold')
plt.tight_layout()
plt.show()
主程序运行
def main():
"""主程序:运行完整分析"""
print("="*60)
print("足球运动员高速跑动性能分析系统".center(50))
print("="*60)
# 1. 初始化并生成数据
analyzer = PlayerPerformanceAnalyzer()
raw_data = analyzer.generate_player_data(num_players=8, matches_per_player=10)
print(f"\n生成数据成功!共 {len(raw_data)} 条比赛记录")
print(f"参与分析的球员数量:{raw_data['player_id'].nunique()}")
print(f"比赛场次:{len(raw_data)}")
# 2. 数据分析
print("\n" + "="*60)
print("数据分析中...".center(50))
print("="*60)
player_summary = analyzer.analyze_high_speed_performance()
# 3. 数据展示
print("\n球员综合排名表:")
print("-"*80)
print(player_summary[['场均高速跑动(km)', '高速跑动次数', '冲刺次数',
'最大速度(km/h)', '综合得分']].head(10))
# 4. 可视化
visualizer = PerformanceVisualizer()
# 4.1 主对比图
print("\n生成对比图表...")
visualizer.plot_high_speed_comparison(player_summary)
# 4.2 雷达图
print("生成雷达图...")
visualizer.plot_radar_comparison(player_summary, top_n=4)
# 4.3 按位置分析
print("生成位置对比图...")
visualizer.plot_position_comparison(player_summary)
# 5. 统计分析
print("\n计算相关性矩阵...")
corr_matrix = StatisticalAnalyzer.calculate_correlations(player_summary)
plt.figure(figsize=(10, 8))
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0,
fmt='.2f', square=True, linewidths=1)
plt.title('球员性能指标相关性热力图', fontsize=14, fontweight='bold')
plt.tight_layout()
plt.show()
# 6. 输出关键洞察
print("\n" + "="*60)
print("关键分析洞察:".center(50))
print("="*60)
# 找出最佳球员
best_player = player_summary.index[0]
best_value = player_summary.iloc[0]['综合得分']
print(f"🏆 综合表现最佳球员:{best_player}")
print(f" 综合得分:{best_value:.2f}")
# 找出高速跑动最多的球员
high_speed_player = player_summary['场均高速跑动(km)'].idxmax()
high_speed_value = player_summary.loc[high_speed_player, '场均高速跑动(km)']
print(f"⚡ 场均高速跑动最多:{high_speed_player}")
print(f" 高速跑动距离:{high_speed_value:.2f} km")
# 位置对比分析
position_stats = player_summary.groupby('position').agg({
'综合得分': 'mean'
}).round(2)
print("\n📍 位置表现分析:")
for position, row in position_stats.iterrows():
print(f" {position}: 平均得分 {row['综合得分']:.2f}")
# 相关性强弱
if '场均高速跑动(km)' in corr_matrix and '冲刺次数' in corr_matrix:
corr_val = corr_matrix.loc['场均高速跑动(km)', '冲刺次数']
print(f"\n📊 高速跑动距离与冲刺次数的相关性:{corr_val:.2f}")
if abs(corr_val) > 0.7:
print(" 两者高度相关,表明高速跑动多的球员也倾向于有更多冲刺")
print("\n" + "="*60)
print("分析完成!".center(50))
print("="*60)
if __name__ == "__main__":
main()
运行结果示例
运行程序后会生成:
- 球员综合排名表 - 展示所有球员的各项指标
- 高速跑动距离对比图 - 柱状图+饼图+散点图+排名图
- 多维性能雷达图 - 对比前4名球员的综合表现
- 位置对比分析图 - 不同位置球员的特点
- 相关性热力图 - 展示各项指标之间的关系
- 文字分析洞察 - 关键发现和结论
代码特点
- 模块化设计:数据分析、可视化、统计分离
- 完整的数据流:从数据生成到可视化展示
- 多维度分析:球员个体、位置对比、指标相关性
- 直观可视化:5种以上图表展示不同视角
- 实用的分析洞察:自动输出关键发现
这个案例涵盖了Python数据分析的完整流程,包括数据处理、统计分析、可视化呈现等多个方面,适合作为综合实践项目。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播