本文目录导读:

我来为您提供一个统计门球短传配合成功率的Python案例。
数据模型设计
import pandas as pd
import numpy as np
from datetime import datetime
import matplotlib.pyplot as plt
import seaborn as sns
class ShortPassData:
"""短传配合数据模型"""
def __init__(self):
self.data = []
def add_pass(self, game_id, attacker, passer, receiver,
distance, pressure_level, success, time_minute):
"""添加单次传球记录"""
self.data.append({
'game_id': game_id,
'attacker': attacker,
'passer': passer,
'receiver': receiver,
'distance': distance,
'pressure_level': pressure_level, # 1-5, 5为最高压力
'success': success, # True/False
'time_minute': time_minute
})
def to_dataframe(self):
"""转换为DataFrame"""
return pd.DataFrame(self.data)
# 创建模拟数据
def generate_sample_data():
"""生成模拟的门球短传数据"""
data = ShortPassData()
# 模拟10场比赛的数据
np.random.seed(42)
players = ['Player_A', 'Player_B', 'Player_C', 'Player_D', 'Player_E']
for game in range(1, 11):
for _ in range(np.random.randint(20, 40)): # 每场20-40次短传
passer = np.random.choice(players)
receiver = np.random.choice([p for p in players if p != passer])
data.add_pass(
game_id=f'Game_{game:02d}',
attacker='Team1',
passer=passer,
receiver=receiver,
distance=np.random.uniform(1, 15), # 1-15米短传
pressure_level=np.random.randint(1, 6),
success=np.random.random() > 0.3, # 70%成功率基线
time_minute=np.random.randint(1, 91)
)
return data.to_dataframe()
统计分析函数
class ShortPassAnalyzer:
"""短传配合分析器"""
def __init__(self, df):
self.df = df
self.total_passes = len(df)
self.successful_passes = df[df['success'] == True].shape[0]
def overall_success_rate(self):
"""总体成功率"""
rate = self.successful_passes / self.total_passes * 100
return {
'total_passes': self.total_passes,
'successful_passes': self.successful_passes,
'success_rate': round(rate, 2)
}
def player_success_rate(self):
"""球员个人成功率"""
player_stats = []
for player in self.df['passer'].unique():
player_passes = self.df[self.df['passer'] == player]
total = len(player_passes)
success = player_passes['success'].sum()
rate = (success / total * 100) if total > 0 else 0
player_stats.append({
'player': player,
'total_passes': total,
'successful_passes': success,
'success_rate': round(rate, 2)
})
return pd.DataFrame(player_stats)
def distance_analysis(self):
"""距离分析"""
# 按距离区间分组
distance_bins = [0, 3, 6, 9, 12, 15]
labels = ['0-3m', '3-6m', '6-9m', '9-12m', '12-15m']
self.df['distance_group'] = pd.cut(
self.df['distance'],
bins=distance_bins,
labels=labels
)
distance_stats = []
for group in labels:
group_data = self.df[self.df['distance_group'] == group]
total = len(group_data)
success = group_data['success'].sum() if total > 0 else 0
rate = (success / total * 100) if total > 0 else 0
distance_stats.append({
'distance_group': group,
'total_passes': total,
'successful_passes': success,
'success_rate': round(rate, 2)
})
return pd.DataFrame(distance_stats)
def pressure_analysis(self):
"""压力等级分析"""
pressure_stats = []
for level in range(1, 6):
level_data = self.df[self.df['pressure_level'] == level]
total = len(level_data)
success = level_data['success'].sum() if total > 0 else 0
rate = (success / total * 100) if total > 0 else 0
pressure_stats.append({
'pressure_level': level,
'total_passes': total,
'successful_passes': success,
'success_rate': round(rate, 2)
})
return pd.DataFrame(pressure_stats)
def game_progression_analysis(self):
"""比赛进程分析(每15分钟分段)"""
time_bins = [0, 15, 30, 45, 60, 75, 90]
labels = ['0-15min', '15-30min', '30-45min', '45-60min', '60-75min', '75-90min']
self.df['time_group'] = pd.cut(
self.df['time_minute'],
bins=time_bins,
labels=labels
)
time_stats = []
for group in labels:
group_data = self.df[self.df['time_group'] == group]
total = len(group_data)
success = group_data['success'].sum() if total > 0 else 0
rate = (success / total * 100) if total > 0 else 0
time_stats.append({
'time_period': group,
'total_passes': total,
'successful_passes': success,
'success_rate': round(rate, 2)
})
return pd.DataFrame(time_stats)
def partner_analysis(self):
"""球员配合分析"""
partner_stats = []
for passer in self.df['passer'].unique():
for receiver in self.df['receiver'].unique():
if passer != receiver:
pairs = self.df[
(self.df['passer'] == passer) &
(self.df['receiver'] == receiver)
]
total = len(pairs)
if total > 0:
success = pairs['success'].sum()
rate = (success / total * 100)
partner_stats.append({
'passer': passer,
'receiver': receiver,
'total_passes': total,
'successful_passes': success,
'success_rate': round(rate, 2)
})
return pd.DataFrame(partner_stats)
# 生成报告函数
def generate_analysis_report(analyzer):
"""生成分析报告"""
print("=" * 60)
print("门球短传配合统计报告")
print("=" * 60)
# 1. 总体统计
print("\n1. 总体成功率")
print("-" * 40)
overall = analyzer.overall_success_rate()
print(f"总传球次数: {overall['total_passes']}")
print(f"成功传球次数: {overall['successful_passes']}")
print(f"总体成功率: {overall['success_rate']}%")
# 2. 球员统计
print("\n2. 球员个人成功率")
print("-" * 40)
player_stats = analyzer.player_success_rate()
print(player_stats.to_string(index=False))
# 3. 距离分析
print("\n3. 传球距离分析")
print("-" * 40)
distance_stats = analyzer.distance_analysis()
print(distance_stats.to_string(index=False))
# 4. 压力分析
print("\n4. 压力等级分析")
print("-" * 40)
pressure_stats = analyzer.pressure_analysis()
print(pressure_stats.to_string(index=False))
# 5. 比赛进程分析
print("\n5. 比赛进程分析")
print("-" * 40)
time_stats = analyzer.game_progression_analysis()
print(time_stats.to_string(index=False))
# 可视化函数
def create_visualizations(analyzer):
"""创建可视化图表"""
fig, axes = plt.subplots(2, 2, figsize=(15, 12))
# 1. 球员成功率对比
ax1 = axes[0, 0]
player_stats = analyzer.player_success_rate()
ax1.bar(player_stats['player'], player_stats['success_rate'])
ax1.set_title('球员短传成功率对比')
ax1.set_xlabel('球员')
ax1.set_ylabel('成功率 (%)')
ax1.set_ylim(0, 100)
for i, v in enumerate(player_stats['success_rate']):
ax1.text(i, v + 1, f'{v}%', ha='center')
# 2. 距离与成功率关系
ax2 = axes[0, 1]
distance_stats = analyzer.distance_analysis()
ax2.plot(distance_stats['distance_group'],
distance_stats['success_rate'],
marker='o', linewidth=2, markersize=8)
ax2.set_title('传球距离与成功率关系')
ax2.set_xlabel('距离分组')
ax2.set_ylabel('成功率 (%)')
ax2.set_ylim(0, 100)
# 3. 压力等级影响
ax3 = axes[1, 0]
pressure_stats = analyzer.pressure_analysis()
ax3.bar(pressure_stats['pressure_level'].astype(str),
pressure_stats['success_rate'])
ax3.set_title('防守压力对成功率的影响')
ax3.set_xlabel('压力等级 (1-5)')
ax3.set_ylabel('成功率 (%)')
ax3.set_ylim(0, 100)
# 4. 比赛进程趋势
ax4 = axes[1, 1]
time_stats = analyzer.game_progression_analysis()
ax4.plot(time_stats['time_period'],
time_stats['success_rate'],
marker='s', linewidth=2, markersize=8, color='green')
ax4.set_title('比赛进程成功率变化')
ax4.set_xlabel('时间分段')
ax4.set_ylabel('成功率 (%)')
ax4.set_ylim(0, 100)
plt.tight_layout()
plt.show()
# 主程序
if __name__ == "__main__":
# 生成数据
print("正在生成模拟数据...")
df = generate_sample_data()
# 创建分析器
analyzer = ShortPassAnalyzer(df)
# 生成报告
generate_analysis_report(analyzer)
# 创建可视化
create_visualizations(analyzer)
# 额外分析:最佳配合组合
print("\n6. 最佳配合组合(Top 5)")
print("-" * 40)
partner_stats = analyzer.partner_analysis()
top_partners = partner_stats.nlargest(5, 'success_rate')
print(top_partners.to_string(index=False))
使用示例
# 简单的使用示例
if __name__ == "__main__":
# 生成数据
data = generate_sample_data()
# 创建分析器
analyzer = ShortPassAnalyzer(data)
# 获取总体成功率
print("总体成功率:", analyzer.overall_success_rate())
# 查看球员数据
player_stats = analyzer.player_success_rate()
print("\n球员统计:")
print(player_stats)
# 查看距离分析
distance_stats = analyzer.distance_analysis()
print("\n距离分析:")
print(distance_stats)
这个案例提供了完整的门球短传配合统计框架,包括:
- 数据收集:模拟球员传球数据
- 多维度分析:球员、距离、压力、比赛进程等
- 可视化报告:图表展示分析结果
- 配合分析:统计球员间配合成功率
您可以根据实际数据格式调整数据导入方式,并根据需要扩展更多分析维度。