我来设计一个综合的Python案例,对比不同球员的点球命中率,并进行数据分析和可视化。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
import warnings
warnings.filterwarnings('ignore')
# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 创建点球数据集
def create_penalty_data():
"""创建点球数据集"""
np.random.seed(42)
# 定义球员数据
players_data = {
'球员': ['梅西', 'C罗', '莱万', '凯恩', '姆巴佩',
'内马尔', '萨拉赫', '本泽马', '哈兰德', '德布劳内'],
'俱乐部': ['迈阿密国际', '利雅得胜利', '巴萨', '拜仁', '皇马',
'利雅得新月', '利物浦', '皇马', '曼城', '曼城'],
'国籍': ['阿根廷', '葡萄牙', '波兰', '英格兰', '法国',
'巴西', '埃及', '法国', '挪威', '比利时'],
'年龄': [36, 38, 35, 30, 25, 31, 31, 35, 23, 32],
'点球总数': [145, 170, 82, 68, 45, 72, 58, 42, 28, 36],
}
df = pd.DataFrame(players_data)
# 根据球员实力生成命中率(真实世界的大致数据)
base_accuracy = {
'梅西': 0.78, 'C罗': 0.84, '莱万': 0.78, '凯恩': 0.88, '姆巴佩': 0.82,
'内马尔': 0.80, '萨拉赫': 0.84, '本泽马': 0.74, '哈兰德': 0.86, '德布劳内': 0.80
}
# 添加噪声模拟真实数据
df['命中率'] = [base_accuracy[player] + np.random.normal(0, 0.02)
for player in df['球员']]
df['命中率'] = np.clip(df['命中率'], 0.6, 0.95)
# 计算命中数(舍入到整数)
df['命中数'] = (df['点球总数'] * df['命中率']).round().astype(int)
df['命中率'] = (df['命中数'] / df['点球总数'] * 100).round(2)
return df
# 创建详细比赛数据用于时间序列分析
def create_match_data(players):
"""创建每个球员在不同赛季的点球数据"""
np.random.seed(123)
seasons = ['2018-19', '2019-20', '2020-21', '2021-22', '2022-23']
data_list = []
for player in players:
base_rate = 0.75 + np.random.random() * 0.1
for season in seasons:
# 每个赛季点球数量
penalties = np.random.randint(5, 15)
# 命中率有轻微波动
season_rate = base_rate + np.random.normal(0, 0.05)
season_rate = np.clip(season_rate, 0.6, 0.95)
goals = round(penalties * season_rate)
data_list.append({
'球员': player,
'赛季': season,
'点球数': penalties,
'命中数': goals,
'命中率': goals/penalties*100
})
return pd.DataFrame(data_list)
# 初始化数据
df_players = create_penalty_data()
df_matches = create_match_data(df_players['球员'].tolist())
print("="*60)
print("点球数据概览")
print("="*60)
print(df_players[['球员', '俱乐部', '点球总数', '命中数', '命中率']].to_string(index=False))
# 1. 基本统计分析
print("\n" + "="*60)
print("基本统计信息")
print("="*60)
print(f"平均命中率: {df_players['命中率'].mean():.2f}%")
print(f"最高命中率: {df_players['命中率'].max():.2f}%")
print(f"最低命中率: {df_players['命中率'].min():.2f}%")
print(f"命中率标准差: {df_players['命中率'].std():.2f}")
# 2. 创建可视化
fig, axes = plt.subplots(2, 3, figsize=(18, 12))
fig.suptitle('点球命中率综合分析', fontsize=16, fontweight='bold')
# 2.1 命中率排名条形图
ax1 = axes[0, 0]
sorted_df = df_players.sort_values('命中率', ascending=True)
bars = ax1.barh(sorted_df['球员'], sorted_df['命中率'],
color=plt.cm.RdYlGn(np.linspace(0.2, 0.8, len(sorted_df))))
ax1.set_xlabel('命中率 (%)')
ax1.set_title('点球命中率排名')
# 添加数据标签
for i, (bar, rate) in enumerate(zip(bars, sorted_df['命中率'])):
ax1.text(bar.get_width()+0.5, bar.get_y()+bar.get_height()/2,
f'{rate:.1f}%', va='center', fontweight='bold')
# 2.2 点球数量与命中率散点图
ax2 = axes[0, 1]
scatter = ax2.scatter(df_players['点球总数'], df_players['命中率'],
c=df_players['命中率'], s=100, cmap='viridis', alpha=0.7)
ax2.set_xlabel('点球总次数')
ax2.set_ylabel('命中率 (%)')
ax2.set_title('点球数量 vs 命中率')
plt.colorbar(scatter, ax=ax2, label='命中率')
# 添加球员标签
for _, row in df_players.iterrows():
ax2.annotate(row['球员'], (row['点球总数'], row['命中率']),
fontsize=8, ha='right')
# 2.3 年龄与命中率的关系
ax3 = axes[0, 2]
scatter2 = ax3.scatter(df_players['年龄'], df_players['命中率'],
s=df_players['点球总数'], alpha=0.6, c='red')
ax3.set_xlabel('年龄')
ax3.set_ylabel('命中率 (%)')
ax3.set_title('年龄 vs 命中率(气泡大小=点球数)')
# 添加趋势线
z = np.polyfit(df_players['年龄'], df_players['命中率'], 1)
p = np.poly1d(z)
ax3.plot(df_players['年龄'], p(df_players['年龄']), "r--", alpha=0.8, label='趋势线')
ax3.legend()
# 2.4 俱乐部命中率对比
ax4 = axes[1, 0]
club_stats = df_players.groupby('俱乐部')['命中率'].mean().sort_values()
colors = plt.cm.Set3(np.linspace(0, 1, len(club_stats)))
ax4.barh(club_stats.index, club_stats.values, color=colors)
ax4.set_xlabel('平均命中率 (%)')
ax4.set_title('各俱乐部球员平均命中率')
for i, (club, rate) in enumerate(club_stats.items()):
ax4.text(rate+0.2, i, f'{rate:.2f}%', va='center', fontweight='bold')
# 2.5 赛季命中率趋势
ax5 = axes[1, 1]
# 选择几位代表球员
representative_players = ['梅西', 'C罗', '哈兰德', '凯恩']
season_data = df_matches[df_matches['球员'].isin(representative_players)]
for player in representative_players:
player_data = season_data[season_data['球员'] == player]
ax5.plot(player_data['赛季'], player_data['命中率'],
marker='o', label=player, linewidth=2, markersize=8)
ax5.set_xlabel('赛季')
ax5.set_ylabel('命中率 (%)')
ax5.set_title('代表球员赛季命中率趋势')
ax5.legend()
ax5.grid(True, alpha=0.3)
# 2.6 命中率分布直方图
ax6 = axes[1, 2]
ax6.hist(df_players['命中率'], bins=8, alpha=0.7, color='steelblue', edgecolor='black')
ax6.axvline(df_players['命中率'].mean(), color='red', linestyle='--',
label=f'均值: {df_players["命中率"].mean():.1f}%')
ax6.axvline(df_players['命中率'].median(), color='green', linestyle='--',
label=f'中位数: {df_players["命中率"].median():.1f}%')
ax6.set_xlabel('命中率 (%)')
ax6.set_ylabel('球员数量')
ax6.set_title('命中率分布')
ax6.legend()
ax6.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('penalty_analysis.png', dpi=300, bbox_inches='tight')
plt.show()
# 3. 统计分析
print("\n" + "="*60)
print("统计分析")
print("="*60)
# 3.1 相关性分析
print("\n相关性分析:")
corr_age_rate = stats.pearsonr(df_players['年龄'], df_players['命中率'])
print(f"年龄与命中率的相关性: r={corr_age_rate[0]:.3f}, p={corr_age_rate[1]:.4f}")
corr_total_rate = stats.pearsonr(df_players['点球总数'], df_players['命中率'])
print(f"点球数量与命中率的相关性: r={corr_total_rate[0]:.3f}, p={corr_total_rate[1]:.4f}")
# 3.2 假设检验
print("\n假设检验:")
# 比较前5名和后5名球员的命中率
top5 = df_players.nlargest(5, '命中率')['命中率']
bottom5 = df_players.nsmallest(5, '命中率')['命中率']
t_stat, p_value = stats.ttest_ind(top5, bottom5)
print(f"前5名 vs 后5名命中率对比: t={t_stat:.3f}, p={p_value:.4f}")
# 3.3 置信区间
print("\n置信区间(95%):")
for _, row in df_players.iterrows():
ci_low, ci_high = stats.binom.interval(0.95, row['点球总数'],
row['命中数']/row['点球总数'])
print(f"{row['球员']}: {ci_low*100:.1f}% - {ci_high*100:.1f}%")
# 4. 高级分析
print("\n" + "="*60)
print("高级分析")
print("="*60)
# 4.1 聚类分析(简化版)
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
X = df_players[['年龄', '点球总数', '命中率']]
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# K-means聚类
kmeans = KMeans(n_clusters=3, random_state=42)
df_players['聚类'] = kmeans.fit_predict(X_scaled)
print("\n球员聚类分析:")
for cluster in sorted(df_players['聚类'].unique()):
cluster_players = df_players[df_players['聚类'] == cluster]
print(f"\n聚类 {cluster} ({len(cluster_players)}人):")
for _, row in cluster_players.iterrows():
print(f" {row['球员']}: 年龄={row['年龄']}, 点球数={row['点球总数']}, 命中率={row['命中率']}%")
# 4.2 教练视角分析
print("\n" + "="*60)
print("训练建议")
print("="*60)
# 按命中率排序给出建议
sorted_final = df_players.sort_values('命中率', ascending=False)
for i, (_, row) in enumerate(sorted_final.iterrows()):
if row['命中率'] < 70:
status = "⚠️ 需要重点加强"
elif row['命中率'] < 80:
status = "需要持续训练"
else:
status = "✅ 表现优秀"
print(f"{row['球员']}: 命中率{row['命中率']:.1f}% - {status}")
# 5. 预测模型(简化版)
print("\n" + "="*60)
print("未来表现预测")
print("="*60)
from sklearn.linear_model import LinearRegression
# 基于年龄预测命中率
X_age = df_players['年龄'].values.reshape(-1, 1)
y_rate = df_players['命中率'].values
lr = LinearRegression()
lr.fit(X_age, y_rate)
# 预测未来两年的命中率
future_ages = df_players['年龄'] + 2
predictions = lr.predict(future_ages.values.reshape(-1, 1))
print("\n预测两年后的命中率:")
for i, player in enumerate(df_players['球员']):
change = predictions[i] - df_players['命中率'].iloc[i]
trend = "上升" if change > 0 else "下降"
print(f"{player}: 当前{df_players['命中率'].iloc[i]:.1f}% → 预测{predictions[i]:.1f}% ({trend})")
#
print("\n" + "="*60)
print("综合分析结论")
print("="*60)
best_player = df_players.loc[df_players['命中率'].idxmax()]
worst_player = df_players.loc[df_players['命中率'].idxmin()]
print(f"\n🏆 最佳点球手: {best_player['球员']} (命中率: {best_player['命中率']:.1f}%)")
print(f"📉 最具提升空间: {worst_player['球员']} (命中率: {worst_player['命中率']:.1f}%)")
print(f"\n📊 关键发现:")
print(f"1. 平均点球命中率: {df_players['命中率'].mean():.1f}%")
print(f"2. 年轻球员(<30岁)平均命中率: {df_players[df_players['年龄']<30]['命中率'].mean():.1f}%")
print(f"3. 老将球员(≥30岁)平均命中率: {df_players[df_players['年龄']>=30]['命中率'].mean():.1f}%")
print(f"4. 点球命中率与球员年龄的相关性: {corr_age_rate[0]:.3f}")
# 导出数据
df_players.to_csv('penalty_data.csv', index=False)
print("\n✅ 数据已导出至 penalty_data.csv")
这个案例包含了以下功能:
主要功能特点:
-
数据生成与处理
- 模拟真实球员数据
- 包含球员基本信息
- 生成多赛季点球数据
-
全面统计分析
- 描述性统计
- 相关性分析
- 假设检验
- 置信区间计算
-
丰富的数据可视化
- 命中率排名条形图
- 散点图分析
- 趋势图
- 分布直方图
-
机器学习应用
- K-means聚类分析
- 线性回归预测
- 未来表现预测
-
实战决策支持
- 训练建议
- 球员评估
- 趋势预测
这个案例展示了Python在体育数据分析中的综合应用,包括数据清洗、统计分析、可视化和预测建模等多个方面。