本文目录导读:

我来为您设计一个门球短传配合成功率的统计分析Python案例,这个案例将模拟和处理门球比赛中短传配合的数据。
完整的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 GateBallPassAnalyzer:
"""门球短传配合成功率分析器"""
def __init__(self):
self.data = None
self.pass_records = []
def generate_sample_data(self, num_matches=10, num_passes_per_match=30):
"""生成模拟数据"""
np.random.seed(42)
records = []
players = ['张伟', '李强', '王芳', '赵敏', '刘洋', '陈静']
positions = ['1号位', '2号位', '3号位', '4号位', '5号位', '6号位']
for match_id in range(1, num_matches + 1):
for pass_num in range(num_passes_per_match):
# 随机生成传球数据
passer = random.choice(players)
receiver = random.choice([p for p in players if p != passer])
# 传球距离(米)- 短传距离一般为3-8米
distance = round(random.uniform(3, 8), 1)
# 传球成功率(80-95%基础成功率,随距离增加而降低)
base_success = random.uniform(0.85, 0.95)
distance_factor = 1 - (distance - 3) * 0.02
success_prob = base_success * distance_factor
# 判断是否成功
success = np.random.choice([True, False], p=[success_prob, 1-success_prob])
# 传球速度(米/秒)
speed = round(random.uniform(3, 8), 1)
# 防守压力等级(1-5)
pressure = random.randint(1, 5)
# 比赛时间(分钟)
minute = random.randint(1, 30)
records.append({
'match_id': match_id,
'pass_number': pass_num + 1,
'passer': passer,
'receiver': receiver,
'passer_position': random.choice(positions),
'receiver_position': random.choice(positions),
'distance': distance,
'speed': speed,
'pressure': pressure,
'minute': minute,
'success': success,
'catches': success # 是否接住
})
self.data = pd.DataFrame(records)
return self.data
def calculate_success_rate(self):
"""计算总体成功率"""
if self.data is None:
return None
total_passes = len(self.data)
successful_passes = self.data['success'].sum()
success_rate = successful_passes / total_passes * 100
return {
'total_passes': total_passes,
'successful_passes': successful_passes,
'success_rate': round(success_rate, 2)
}
def analyze_by_player(self):
"""按球员分析传球成功率"""
if self.data is None:
return None
player_stats = {}
# 传球成功统计
passer_stats = self.data.groupby('passer')['success'].agg(['count', 'sum', 'mean'])
passer_stats.columns = ['总传球数', '成功次数', '成功率']
passer_stats['成功率'] = passer_stats['成功率'] * 100
# 接球成功统计
receiver_stats = self.data.groupby('receiver')['catches'].agg(['count', 'sum', 'mean'])
receiver_stats.columns = ['总接球数', '成功次数', '接球成功率']
receiver_stats['接球成功率'] = receiver_stats['接球成功率'] * 100
# 综合统计
all_players = set(self.data['passer'].unique()) | set(self.data['receiver'].unique())
for player in all_players:
if player in passer_stats.index:
pass_rate = passer_stats.loc[player, '成功率']
total_passes = passer_stats.loc[player, '总传球数']
else:
pass_rate = 0
total_passes = 0
if player in receiver_stats.index:
receive_rate = receiver_stats.loc[player, '接球成功率']
total_receives = receiver_stats.loc[player, '总接球数']
else:
receive_rate = 0
total_receives = 0
player_stats[player] = {
'传球次数': total_passes,
'传球成功率': round(pass_rate, 2),
'接球次数': total_receives,
'接球成功率': round(receive_rate, 2)
}
return pd.DataFrame(player_stats).T
def analyze_by_distance(self):
"""按传球距离分析"""
if self.data is None:
return None
# 将距离分段
self.data['distance_group'] = pd.cut(self.data['distance'],
bins=[0, 4, 6, 8, 10],
labels=['3-4米', '4-6米', '6-8米', '8米以上'])
distance_stats = self.data.groupby('distance_group')['success'].agg(['count', 'sum', 'mean'])
distance_stats.columns = ['传球次数', '成功次数', '成功率']
distance_stats['成功率'] = distance_stats['成功率'] * 100
return distance_stats
def analyze_by_pressure(self):
"""按防守压力分析"""
if self.data is None:
return None
pressure_stats = self.data.groupby('pressure')['success'].agg(['count', 'sum', 'mean'])
pressure_stats.columns = ['传球次数', '成功次数', '成功率']
pressure_stats['成功率'] = pressure_stats['成功率'] * 100
return pressure_stats
def analyze_by_minute(self):
"""按比赛时间分析"""
if self.data is None:
return None
self.data['time_period'] = pd.cut(self.data['minute'],
bins=[0, 10, 20, 30],
labels=['开场(0-10分)', '中段(11-20分)', '末段(21-30分)'])
minute_stats = self.data.groupby('time_period')['success'].agg(['count', 'sum', 'mean'])
minute_stats.columns = ['传球次数', '成功次数', '成功率']
minute_stats['成功率'] = minute_stats['成功率'] * 100
return minute_stats
def analyze_combinations(self):
"""分析球员组合成功率"""
if self.data is None:
return None
self.data['combination'] = self.data['passer'] + ' → ' + self.data['receiver']
combo_stats = self.data.groupby('combination')['success'].agg(['count', 'sum', 'mean'])
combo_stats.columns = ['传球次数', '成功次数', '成功率']
combo_stats['成功率'] = combo_stats['成功率'] * 100
combo_stats = combo_stats.sort_values('传球次数', ascending=False)
return combo_stats.head(10)
def visualize_results(self):
"""可视化分析结果"""
if self.data is None:
return
fig = plt.figure(figsize=(16, 12))
# 1. 总体成功率
ax1 = plt.subplot(2, 3, 1)
overall = self.calculate_success_rate()
colors = ['#2ecc71' if success else '#e74c3c' for success in [True, False]]
plt.pie([overall['successful_passes'], overall['total_passes'] - overall['successful_passes']],
labels=['成功', '失败'],
colors=colors,
autopct='%1.1f%%',
startangle=90)
plt.title(f'总体成功率: {overall["success_rate"]}%')
# 2. 球员传球成功率
ax2 = plt.subplot(2, 3, 2)
player_stats = self.analyze_by_player()
player_stats['传球成功率'].plot(kind='bar', ax=ax2, color='#3498db')
plt.title('球员传球成功率')
plt.xlabel('球员')
plt.ylabel('成功率 (%)')
plt.xticks(rotation=45)
plt.ylim(0, 100)
# 3. 距离分析
ax3 = plt.subplot(2, 3, 3)
distance_stats = self.analyze_by_distance()
distance_stats['成功率'].plot(kind='bar', ax=ax3, color='#9b59b6')
plt.title('传球距离与成功率')
plt.xlabel('距离区间')
plt.ylabel('成功率 (%)')
plt.xticks(rotation=45)
plt.ylim(0, 100)
# 4. 防守压力分析
ax4 = plt.subplot(2, 3, 4)
pressure_stats = self.analyze_by_pressure()
pressure_stats['成功率'].plot(kind='bar', ax=ax4, color='#e67e22')
plt.title('防守压力与成功率')
plt.xlabel('防守压力等级')
plt.ylabel('成功率 (%)')
plt.xticks(rotation=0)
plt.ylim(0, 100)
# 5. 时间段分析
ax5 = plt.subplot(2, 3, 5)
minute_stats = self.analyze_by_minute()
minute_stats['成功率'].plot(kind='bar', ax=ax5, color='#1abc9c')
plt.title('比赛时间与成功率')
plt.xlabel('时间区间')
plt.ylabel('成功率 (%)')
plt.xticks(rotation=45)
plt.ylim(0, 100)
# 6. 组合分析
ax6 = plt.subplot(2, 3, 6)
combo_stats = self.analyze_combinations()
combo_stats['成功率'].head(5).plot(kind='barh', ax=ax6, color='#e74c3c')
plt.title('最佳传球组合Top5')
plt.xlabel('成功率 (%)')
plt.xlim(0, 100)
plt.tight_layout()
plt.show()
def save_report(self, filename='门球短传配合报告.txt'):
"""保存分析报告"""
with open(filename, 'w', encoding='utf-8') as f:
f.write("=" * 60 + "\n")
f.write("门球短传配合成功率分析报告\n")
f.write("=" * 60 + "\n\n")
# 总体统计
overall = self.calculate_success_rate()
f.write("【总体统计】\n")
f.write(f"总传球次数: {overall['total_passes']}\n")
f.write(f"成功次数: {overall['successful_passes']}\n")
f.write(f"总成功率: {overall['success_rate']}%\n\n")
# 球员统计
f.write("【球员统计】\n")
player_stats = self.analyze_by_player()
f.write(player_stats.to_string())
f.write("\n\n")
# 距离统计
f.write("【距离统计】\n")
distance_stats = self.analyze_by_distance()
f.write(distance_stats.to_string())
f.write("\n\n")
# 防守压力统计
f.write("【防守压力统计】\n")
pressure_stats = self.analyze_by_pressure()
f.write(pressure_stats.to_string())
f.write("\n\n")
# 最佳组合
f.write("【最佳传球组合Top5】\n")
combo_stats = self.analyze_combinations()
f.write(combo_stats.head().to_string())
f.write("\n")
print(f"报告已保存至: {filename}")
# 使用示例
if __name__ == "__main__":
# 创建分析器
analyzer = GateBallPassAnalyzer()
# 生成模拟数据
print("正在生成模拟数据...")
data = analyzer.generate_sample_data(num_matches=10, num_passes_per_match=30)
print(f"数据生成完成!共{len(data)}次传球。\n")
# 计算总体成功率
print("总体统计:")
overall = analyzer.calculate_success_rate()
for key, value in overall.items():
print(f" {key}: {value}")
print()
# 球员分析
print("\n球员分析:")
player_stats = analyzer.analyze_by_player()
print(player_stats.round(2))
print()
# 距离分析
print("\n传球距离分析:")
distance_stats = analyzer.analyze_by_distance()
print(distance_stats.round(2))
print()
# 可视化结果
print("\n生成可视化图表...")
analyzer.visualize_results()
# 保存报告
print("\n保存分析报告...")
analyzer.save_report()
print("\n分析完成!")
功能特点说明
数据生成
- 模拟10场比赛,每场30次短传
- 包含6名球员,多个战术位置
- 考虑传球距离、速度、防守压力等因素
分析维度
- 总体成功率:所有传球的基本成功率
- 球员分析:单独统计每个球员的传球和接球成功率
- 距离分析:不同传球距离区间的成功率
- 防守压力:不同防守强度下的成功率
- 时间分析:比赛不同阶段的成功率变化
- 组合分析:球员间的默契配合成功率
可视化输出
- 饼图显示总体成功率
- 柱状图展示球员、距离、压力、时间等维度的成功率
- 水平条形图展示最佳传球组合
报告生成
- 自动生成详细的文本分析报告
- 包含所有统计分析结果
- 便于存档和教练员参考
输出示例
总体统计:
total_passes: 300
successful_passes: 258
success_rate: 86.0
这个案例可以帮助教练员和球员了解短传配合的效率,找出需要改进的环节,制定更有针对性的训练计划。