本文目录导读:

我来为您设计一个统计弧线球传中精准度的Python案例,这个案例将模拟足球比赛中的弧线球传中数据,并进行分析统计。
完整案例代码
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime
import random
# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
class CrossPassAnalyzer:
"""弧线球传中分析器"""
def __init__(self):
self.data = None
self.player_stats = None
self.team_stats = None
def generate_match_data(self, num_matches=10, players_per_team=11):
"""生成模拟比赛数据"""
# 定义球员和队伍
teams = ['皇马', '巴萨', '曼城', '利物浦', '拜仁', '巴黎']
all_data = []
match_id = 0
positions = ['左边锋', '右边锋', '中场', '后卫']
for match in range(num_matches):
match_id += 1
home_team = random.choice(teams)
away_team = random.choice([t for t in teams if t != home_team])
# 为每支队伍生成球员
for team in [home_team, away_team]:
for player_num in range(1, players_per_team + 1):
# 每场比赛每个球员产生10-30次传中
num_crosses = random.randint(10, 30)
for cross_num in range(num_crosses):
# 生成传中数据
cross_type = random.choice(['高弧线', '低平弧线', '内旋弧线', '外旋弧线'])
# 计算精准度(基于球员能力和随机因素)
player_skill = random.uniform(0.5, 0.95)
random_factor = random.uniform(-0.1, 0.1)
success_probability = max(0, min(1, player_skill + random_factor))
data = {
'match_id': match_id,
'team': team,
'opponent': home_team if team == away_team else away_team,
'player_number': player_num,
'player_position': random.choice(positions),
'cross_type': cross_type,
'swing_angle': random.randint(30, 75), # 弧线角度
'cross_distance': random.randint(15, 40), # 传中距离(米)
'chip_height': random.randint(10, 30), # 弧线高度(米)
'success': 1 if random.random() < success_probability else 0,
'assist': 1 if random.random() < 0.15 and success_probability > 0.7 else 0,
'defense_pressure': random.choice(['紧逼', '一般', '自由']),
'match_minute': random.randint(1, 95)
}
all_data.append(data)
# 转换为DataFrame
self.data = pd.DataFrame(all_data)
# 添加更多派生的特征
self.data['success_rate'] = self.data['success'].mean()
self.data['distance_bin'] = pd.cut(self.data['cross_distance'],
bins=[0, 20, 30, 45],
labels=['短距离', '中距离', '长距离'])
self.data['angle_bin'] = pd.cut(self.data['swing_angle'],
bins=[0, 45, 60, 76],
labels=['小弧线', '中弧线', '大弧线'])
return self.data
def calculate_player_stats(self):
"""计算球员统计数据"""
if self.data is None:
raise ValueError("请先生成数据")
stats = self.data.groupby(['team', 'player_number', 'player_position']).agg({
'success': ['count', 'sum', 'mean'],
'assist': 'sum',
'cross_distance': 'mean',
'swing_angle': 'mean',
'chip_height': 'mean'
}).round(3)
# 重命名列
stats.columns = ['总传中', '成功传中', '精准率', '助攻',
'平均距离', '平均弧线角度', '平均弧线高度']
stats = stats.reset_index()
# 排序按精准率
stats = stats.sort_values('精准率', ascending=False)
self.player_stats = stats
return stats
def calculate_position_stats(self):
"""计算位置统计"""
if self.data is None:
raise ValueError("请先生成数据")
position_stats = self.data.groupby(['player_position', 'cross_type']).agg({
'success': ['count', 'sum', 'mean'],
'team': 'first'
}).round(3)
position_stats.columns = ['传中次数', '成功次数', '精准率', '球队']
position_stats = position_stats.reset_index()
return position_stats
def analyze_angle_effect(self):
"""分析弧线角度对精准度的影响"""
if self.data is None:
raise ValueError("请先生成数据")
# 按弧线角度分箱统计
angle_stats = self.data.groupby(self.data['angle_bin']).agg({
'success': ['count', 'mean'],
'assist': 'sum'
}).round(3)
angle_stats.columns = ['样本数', '精准率', '助攻数']
angle_stats = angle_stats.reset_index()
return angle_stats
def visualize_results(self):
"""可视化分析结果"""
if self.player_stats is None:
self.calculate_player_stats()
# 创建图表
fig, axes = plt.subplots(2, 3, figsize=(18, 12))
# 1. 球员精准率分布
axes[0, 0].hist(self.player_stats['精准率'], bins=30, alpha=0.7)
axes[0, 0].set_title('球员传中精准率分布')
axes[0, 0].set_xlabel('精准率')
axes[0, 0].set_ylabel('球员数量')
axes[0, 0].axvline(self.player_stats['精准率'].mean(),
color='r', linestyle='--', label='平均精准率')
axes[0, 0].legend()
# 2. 不同位置的精准率比较
pos_stats = self.player_stats.groupby('player_position')['精准率'].mean()
axes[0, 1].bar(pos_stats.index, pos_stats.values)
axes[0, 1].set_title('不同位置的传中精准率')
axes[0, 1].set_xlabel('位置')
axes[0, 1].set_ylabel('平均精准率')
# 3. 弧线角度与精准率的关系
if hasattr(self, 'data'):
angle_analysis = self.analyze_angle_effect()
axes[0, 2].bar(angle_analysis['angle_bin'].astype(str),
angle_analysis['精准率'])
axes[0, 2].set_title('弧线角度对精准率的影响')
axes[0, 2].set_xlabel('弧线类型')
axes[0, 2].set_ylabel('平均精准率')
# 4. 传中距离对精准率的影响
distance_analysis = self.data.groupby('distance_bin')['success'].mean()
axes[1, 0].bar(range(len(distance_analysis)), distance_analysis.values)
axes[1, 0].set_xticks(range(len(distance_analysis)))
axes[1, 0].set_xticklabels(distance_analysis.index)
axes[1, 0].set_title('传中距离对精准率的影响')
axes[1, 0].set_xlabel('距离类型')
axes[1, 0].set_ylabel('平均精准率')
# 5. 各球员的助攻与精准率散点
axes[1, 1].scatter(self.player_stats['精准率'],
self.player_stats['助攻'],
alpha=0.6)
axes[1, 1].set_title('精准率与助攻关系')
axes[1, 1].set_xlabel('精准率')
axes[1, 1].set_ylabel('助攻数')
# 6. 传中最多的球员Top10
top_players = self.player_stats.nlargest(10, '总传中')
axes[1, 2].bar(top_players['player_number'].astype(str),
top_players['总传中'])
axes[1, 2].set_title('传中最多的球员Top10')
axes[1, 2].set_xlabel('球员号码')
axes[1, 2].set_ylabel('总传中次数')
plt.tight_layout()
plt.show()
def generate_report(self):
"""生成统计报告"""
report = f"""
========== 弧线球传中精准度分析报告 ==========
分析时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
一、整体统计
---------------
总传中次数: {self.data['success'].count()}
成功传中: {self.data['success'].sum()}
整体精准率: {self.data['success'].mean():.3f}
总助攻数: {self.data['assist'].sum()}
二、按位置统计
---------------
"""
pos_stats = self.data.groupby(['player_position']).agg({
'success': ['count', 'mean', 'sum'],
'assist': 'sum'
}).round(3)
for position in pos_stats.index:
report += f"""\n位置: {position}
传中次数: {pos_stats.loc[position, ('success', 'count')]}
精准率: {pos_stats.loc[position, ('success', 'mean')]:.3f}
助攻数: {pos_stats.loc[position, ('assist', 'sum')]}
"""
# 添加最佳球员
best_player = self.player_stats.iloc[0]
report += f"""
三、最佳球员
---------------
最佳精准率的球员: 号码 #{best_player['player_number']} ({best_player['player_position']})
位置: {best_player['player_position']}
精准率: {best_player['精准率']:.3f}
"""
return report
# 使用示例
def main():
"""主函数"""
# 创建分析器
analyzer = CrossPassAnalyzer()
# 生成模拟数据
print("正在生成模拟比赛数据...")
data = analyzer.generate_match_data(num_matches=50)
print(f"数据生成完成!共 {len(data)} 次传中记录")
# 计算统计信息
print("\n正在计算统计信息...")
player_stats = analyzer.calculate_player_stats()
print("球员统计完成!")
# 输出部分统计
print("\n===== 球员精准率统计(前10名)=====")
print(player_stats[['team', 'player_number', 'player_position', '精准率', '助攻']].head(10))
# 位置统计
pos_stats = analyzer.calculate_position_stats()
print("\n===== 位置统计 =====")
print(pos_stats)
# 弧线角度分析
if hasattr(analyzer, 'data'):
angle_stats = analyzer.analyze_angle_effect()
print("\n===== 弧线角度影响分析 =====")
print(angle_stats)
# 生成报告
report = analyzer.generate_report()
print("\n\n", report)
# 可视化
analyzer.visualize_results()
# 提供一些专业建议
print("\n===== 改进建议 =====")
suggestions = analyzer.generate_suggestions() if hasattr(analyzer, 'generate_suggestions') else None
if suggestions:
print(suggestions)
else:
print("1. 从高精准率的球员中,可以重点培养特定位置的传中能力")
print("2. 分析不同弧线角度下的精准率,优化传球选择")
print("3. 注意防守压力对传中精准度的影响")
return analyzer
# 执行主函数
if __name__ == "__main__":
analyzer = main()
扩展功能
您还可以添加以下功能来增强分析:
def generate_suggestions(self):
"""生成改进建议"""
suggestions = []
# 分析最佳位置的传中类型
best_type = self.data[self.data['success']==1].groupby('cross_type').size().idxmax()
suggestions.append(f"最成功的传中类型: {best_type}")
# 分析防守压力影响
pressure_effect = self.data.groupby('defense_pressure')['success'].mean()
suggestions.append(f"自由状态下精准率: {pressure_effect['自由']:.3f}")
suggestions.append(f"紧逼状态下精准率: {pressure_effect['紧逼']:.3f}")
# 找到最佳传球距离
distance_effect = self.data.groupby('distance_bin')['success'].mean()
best_distance = distance_effect.idxmax() if hasattr(distance_effect, 'idxmax') else '中距离'
suggestions.append(f"最佳传中距离: {best_distance}")
return "\n".join(suggestions)
这个案例提供了完整的弧线球传中精准度统计分析功能,包括数据生成、统计分析和可视化,您可以根据实际需求调整参数和增加更多分析维度。