本文目录导读:

我来为您设计一个足球数据分析中统计高球传中争顶成功率的Python案例。
完整代码实现
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime
# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
class AerialDuelsAnalyzer:
"""分析高球传中争顶成功率的类"""
def __init__(self):
self.data = None
self.duel_stats = None
def generate_sample_data(self, n_matches=10, n_players=22):
"""
生成模拟比赛数据
参数:
n_matches: 比赛场次
n_players: 球员数量
"""
np.random.seed(42)
players = []
teams = ['曼联', '曼城', '利物浦', '阿森纳', '切尔西']
for i in range(n_players):
players.append({
'player_id': f'P{i+1:03d}',
'name': f'球员{i+1}',
'team': np.random.choice(teams),
'position': np.random.choice(['前锋', '中场', '后卫', '门将']),
'height': np.random.normal(180, 5), # 身高
'jump_reach': np.random.normal(250, 8) # 弹跳能力
})
# 生成争顶数据
duel_records = []
for match in range(n_matches):
match_date = datetime(2024, 1, 1) + pd.Timedelta(days=match*7)
for player in players:
# 每场比赛每个球员的争顶次数 (近似正态分布)
n_duels = max(0, int(np.random.normal(5, 2)))
for duel in range(n_duels):
# 争顶成功概率与身高、弹跳能力相关
success_prob = 0.5 + (player['height'] - 180) * 0.005 + \
(player['jump_reach'] - 250) * 0.002
success_prob = np.clip(success_prob, 0.1, 0.9)
duel_records.append({
'match_id': match + 1,
'date': match_date,
'player_id': player['player_id'],
'name': player['name'],
'team': player['team'],
'position': player['position'],
'height': player['height'],
'jump_reach': player['jump_reach'],
'success': np.random.binomial(1, success_prob)
})
self.data = pd.DataFrame(duel_records)
return self.data
def calculate_success_rate(self):
"""计算整体和球员级别的争顶成功率"""
# 球员级别统计
player_stats = self.data.groupby(['player_id', 'name', 'team', 'position']).agg({
'success': ['count', 'sum', 'mean']
}).reset_index()
player_stats.columns = ['player_id', 'name', 'team', 'position',
'total_duels', 'won_duels', 'success_rate']
player_stats['success_rate'] = player_stats['success_rate'] * 100
# 球队级别统计
team_stats = self.data.groupby('team').agg({
'success': ['count', 'sum', 'mean']
}).reset_index()
team_stats.columns = ['team', 'total_duels', 'won_duels', 'success_rate']
team_stats['success_rate'] = team_stats['success_rate'] * 100
# 位置级别统计
position_stats = self.data.groupby('position').agg({
'success': ['count', 'sum', 'mean']
}).reset_index()
position_stats.columns = ['position', 'total_duels', 'won_duels', 'success_rate']
position_stats['success_rate'] = position_stats['success_rate'] * 100
self.player_stats = player_stats
self.team_stats = team_stats
self.position_stats = position_stats
return player_stats, team_stats, position_stats
def analyze_height_influence(self, bins=5):
"""分析身高对争顶成功率的影响"""
# 添加身高分组
self.data['height_group'] = pd.cut(self.data['height'],
bins=bins,
labels=['矮', '偏矮', '中等', '偏高', '高'])
height_duels = self.data.groupby('height_group').agg({
'success': ['count', 'sum', 'mean']
}).reset_index()
height_duels.columns = ['height_group', 'total_duels', 'won_duels', 'success_rate']
height_duels['success_rate'] = height_duels['success_rate'] * 100
return height_duels
def calculate_win_probability(self, height, jump_reach):
"""计算争顶成功的概率"""
# 基于历史数据的逻辑回归模型
from sklearn.linear_model import LogisticRegression
X = self.data[['height', 'jump_reach']].values
y = self.data['success'].values
model = LogisticRegression()
model.fit(X, y)
# 预测新数据
prob = model.predict_proba([[height, jump_reach]])[0][1]
return prob, model
def visualize_results(self):
"""可视化分析结果"""
fig, axes = plt.subplots(2, 2, figsize=(15, 12))
# 1. 球队争顶成功率对比
ax1 = axes[0, 0]
sns.barplot(x='team', y='success_rate', data=self.team_stats, ax=ax1)
ax1.set_title('各球队争顶成功率对比')
ax1.set_xlabel('球队')
ax1.set_ylabel('成功率 (%)')
ax1.set_ylim(0, 100)
# 2. 位置争顶成功率对比
ax2 = axes[0, 1]
sns.barplot(x='position', y='success_rate', data=self.position_stats, ax=ax2)
ax2.set_title('不同位置球员争顶成功率')
ax2.set_xlabel('位置')
ax2.set_ylabel('成功率 (%)')
ax2.set_ylim(0, 100)
# 3. 身高与成功率的关系
ax3 = axes[1, 0]
height_duels = self.analyze_height_influence()
sns.barplot(x='height_group', y='success_rate', data=height_duels, ax=ax3)
ax3.set_title('身高与争顶成功率的关系')
ax3.set_xlabel('身高分组')
ax3.set_ylabel('成功率 (%)')
# 4. 球员争顶成功率分布
ax4 = axes[1, 1]
sns.histplot(self.player_stats['success_rate'], bins=10, kde=True, ax=ax4)
ax4.set_title('球员争顶成功率分布')
ax4.set_xlabel('成功率 (%)')
ax4.set_ylabel('人数')
plt.tight_layout()
plt.show()
def get_top_performers(self, n=5):
"""获取争顶表现最好的球员"""
top_players = self.player_stats[
(self.player_stats['total_duels'] >= 10) & # 至少10次争顶
(self.player_stats['success_rate'] > 60) # 成功率超过60%
].sort_values('success_rate', ascending=False).head(n)
return top_players
def analyze_match_trend(self):
"""分析争顶成功率随时间的变化趋势"""
# 按比赛日期统计
self.data['date'] = pd.to_datetime(self.data['date'])
match_trend = self.data.groupby('date').agg({
'success': ['count', 'sum', 'mean']
}).reset_index()
match_trend.columns = ['date', 'total_duels', 'won_duels', 'success_rate']
match_trend['success_rate'] = match_trend['success_rate'] * 100
# 绘制趋势图
plt.figure(figsize=(12, 6))
plt.plot(match_trend['date'], match_trend['success_rate'], marker='o')
plt.title('争顶成功率随时间变化趋势')
plt.xlabel('比赛日期')
plt.ylabel('成功率 (%)')
plt.grid(True, alpha=0.3)
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
return match_trend
# 使用示例
def main():
# 创建分析器实例
analyzer = AerialDuelsAnalyzer()
# 生成模拟数据
print("正在生成模拟数据...")
analyzer.generate_sample_data(n_matches=20, n_players=30)
# 计算统计数据
player_stats, team_stats, position_stats = analyzer.calculate_success_rate()
print("\n" + "="*50)
print("球队争顶成功率统计")
print("="*50)
print(team_stats.to_string(index=False))
print("\n" + "="*50)
print("位置争顶成功率统计")
print("="*50)
print(position_stats.to_string(index=False))
print("\n" + "="*50)
print("表现最佳球员 (争顶成功率 > 60% 且争顶次数 ≥ 10)")
print("="*50)
top_players = analyzer.get_top_performers()
print(top_players.to_string(index=False))
# 预测特定球员的争顶成功率
print("\n" + "="*50)
print("争顶成功率预测")
print("="*50)
height, jump_reach = 185, 262
prob, model = analyzer.calculate_win_probability(height, jump_reach)
print(f"身高 {height}cm, 弹跳 {jump_reach}cm 的球员预测争顶成功率: {prob:.2%}")
# 可视化结果
print("\n正在生成可视化图表...")
analyzer.visualize_results()
# 分析趋势
match_trend = analyzer.analyze_match_trend()
if __name__ == "__main__":
main()
核心功能说明
这个分析系统包含以下主要功能:
- 数据处理:生成模拟足球比赛争顶数据
- 统计分析:计算各维度的争顶成功率
- 影响因素分析:分析身高、位置等因素的影响
- 预测模型:使用机器学习预测争顶成功率
- 可视化展示:生成直观的图表
主要分析方法
| 分析维度 | 方法 | 输出 |
|---|---|---|
| 整体统计 | 描述性统计 | 成功率、争顶次数等 |
| 团队分析 | 分组统计 | 各队成功率对比 |
| 位置分析 | 分组统计 | 不同位置成功率 |
| 身高影响 | 分箱分析 | 身高与成功率关系 |
| 趋势分析 | 时间序列 | 成功率变化趋势 |
使用场景
这个工具可以用于:
- 足球数据分析部门评估球员表现
- 球探系统评估潜在签约球员
- 教练组制定训练计划
- 比赛战术分析
运行代码前需要安装依赖:pip install pandas numpy matplotlib seaborn scikit-learn
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播