本文目录导读:

我来为你提供一个分析进攻三区传球成功率的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 # 用来正常显示负号
# 1. 创建模拟数据
def create_sample_data():
"""创建模拟的传球数据"""
np.random.seed(42)
# 模拟1000次传球数据
n_passes = 1000
data = {
'player_id': np.random.randint(1, 21, n_passes), # 20名球员
'player_name': np.random.choice(['张伟', '李强', '王浩', '刘洋', '陈杰',
'杨帆', '赵磊', '孙斌', '周明', '吴涛',
'郑强', '冯军', '胡飞', '王敏', '李华',
'张磊', '刘强', '陈明', '杨光', '赵勇'], n_passes),
'match_id': np.random.randint(1, 11, n_passes), # 10场比赛
'pass_type': np.random.choice(['短传', '长传', '直塞', '横传', '回传'], n_passes),
'is_attacking_third': np.random.choice([True, False], n_passes, p=[0.4, 0.6]), # 是否进攻三区
'pass_success': np.random.choice([True, False], n_passes, p=[0.75, 0.25]), # 传球成功率
'pass_direction': np.random.choice(['向前', '横向', '向后'], n_passes),
'pressure_level': np.random.choice(['低', '中', '高'], n_passes, p=[0.3, 0.4, 0.3]),
'pass_distance': np.random.uniform(5, 40, n_passes) # 传球距离(米)
}
df = pd.DataFrame(data)
# 逻辑调整:进攻三区的成功率和压力有关
for idx in df.index:
if df.loc[idx, 'is_attacking_third']:
# 进攻三区成功率较低
success_prob = 0.55
if df.loc[idx, 'pressure_level'] == '高':
success_prob = 0.40
elif df.loc[idx, 'pressure_level'] == '低':
success_prob = 0.70
df.loc[idx, 'pass_success'] = np.random.choice([True, False], p=[success_prob, 1-success_prob])
else:
# 非进攻三区成功率较高
success_prob = 0.82
if df.loc[idx, 'pressure_level'] == '高':
success_prob = 0.70
elif df.loc[idx, 'pressure_level'] == '低':
success_prob = 0.90
df.loc[idx, 'pass_success'] = np.random.choice([True, False], p=[success_prob, 1-success_prob])
# 添加时间戳
df['timestamp'] = pd.date_range('2024-01-01', periods=n_passes, freq='30s')
return df
# 2. 数据分析函数
def analyze_attacking_third_passes(df):
"""分析进攻三区传球成功率"""
print("=" * 60)
print("进攻三区传球成功率分析")
print("=" * 60)
# 过滤出进攻三区的传球
attacking_third_passes = df[df['is_attacking_third'] == True]
# 总体成功率
total_passes = len(attacking_third_passes)
successful_passes = attacking_third_passes['pass_success'].sum()
success_rate = successful_passes / total_passes * 100
print(f"\n📊 总体统计:")
print(f"进攻三区传球总次数: {total_passes}")
print(f"成功传球次数: {successful_passes}")
print(f"总体成功率: {success_rate:.2f}%")
# 按传球类型分析
print(f"\n📊 按传球类型分析:")
pass_type_stats = attacking_third_passes.groupby('pass_type')['pass_success'].agg(['mean', 'count'])
pass_type_stats['mean'] = pass_type_stats['mean'] * 100
pass_type_stats.columns = ['成功率(%)', '传球次数']
print(pass_type_stats.round(2))
# 按传球方向分析
print(f"\n📊 按传球方向分析:")
direction_stats = attacking_third_passes.groupby('pass_direction')['pass_success'].agg(['mean', 'count'])
direction_stats['mean'] = direction_stats['mean'] * 100
direction_stats.columns = ['成功率(%)', '传球次数']
print(direction_stats.round(2))
# 按压力等级分析
print(f"\n📊 按压力等级分析:")
pressure_stats = attacking_third_passes.groupby('pressure_level')['pass_success'].agg(['mean', 'count'])
pressure_stats['mean'] = pressure_stats['mean'] * 100
pressure_stats.columns = ['成功率(%)', '传球次数']
print(pressure_stats.round(2))
# 按球员分析
print(f"\n📊 球员表现Top 10:")
player_stats = attacking_third_passes.groupby('player_name')['pass_success'].agg(['mean', 'count']).reset_index()
player_stats['mean'] = player_stats['mean'] * 100
player_stats.columns = ['球员', '成功率(%)', '传球次数']
player_stats = player_stats.sort_values('成功率(%)', ascending=False).head(10)
print(player_stats.round(2))
# 按比赛分析
print(f"\n📊 按比赛分析:")
match_stats = attacking_third_passes.groupby('match_id')['pass_success'].agg(['mean', 'count'])
match_stats['mean'] = match_stats['mean'] * 100
match_stats.columns = ['成功率(%)', '传球次数']
print(match_stats.round(2))
return attacking_third_passes
# 3. 可视化函数
def visualize_analysis(attacking_third_passes, all_passes):
"""创建可视化图表"""
fig, axes = plt.subplots(2, 2, figsize=(15, 12))
fig.suptitle('进攻三区传球成功率分析', fontsize=16, fontweight='bold')
# 1. 整体成功率对比(进攻三区 vs 非进攻三区)
ax1 = axes[0, 0]
zone_comparison = [
attacking_third_passes['pass_success'].mean() * 100,
all_passes[~all_passes['is_attacking_third']]['pass_success'].mean() * 100
]
bars1 = ax1.bar(['进攻三区', '非进攻三区'], zone_comparison, color=['red', 'blue'], alpha=0.7)
ax1.set_ylabel('成功率 (%)')
ax1.set_title('进攻三区 vs 非进攻三区传球成功率')
ax1.set_ylim(0, 100)
for bar, value in zip(bars1, zone_comparison):
ax1.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 1,
f'{value:.1f}%', ha='center', fontsize=12)
# 2. 按传球类型的成功率
ax2 = axes[0, 1]
pass_type_rate = attacking_third_passes.groupby('pass_type')['pass_success'].mean() * 100
sns.barplot(x=pass_type_rate.index, y=pass_type_rate.values, ax=ax2, palette='Set2')
ax2.set_ylabel('成功率 (%)')
ax2.set_title('进攻三区各传球类型成功率')
ax2.set_ylim(0, 100)
for i, v in enumerate(pass_type_rate.values):
ax2.text(i, v + 1, f'{v:.1f}%', ha='center', fontsize=11)
# 3. 压力等级与成功率的关系
ax3 = axes[1, 0]
pressure_data = attacking_third_passes.groupby(['pressure_level', 'pass_success']).size().unstack(fill_value=0)
pressure_data = pressure_data.div(pressure_data.sum(axis=1), axis=0) * 100
pressure_data.plot(kind='bar', stacked=True, ax=ax3, color=['#ff6b6b', '#4ecdc4'])
ax3.set_ylabel('占比 (%)')
ax3.set_title('不同压力等级下的传球结果分布')
ax3.legend(['失败', '成功'], loc='upper right')
ax3.set_xlabel('压力等级')
# 4. 传球距离与成功率的关系(散点图)
ax4 = axes[1, 1]
success_passes = attacking_third_passes[attacking_third_passes['pass_success'] == True]
fail_passes = attacking_third_passes[attacking_third_passes['pass_success'] == False]
ax4.scatter(success_passes['pass_distance'], [1]*len(success_passes),
alpha=0.5, c='green', label='成功', s=60)
ax4.scatter(fail_passes['pass_distance'], [0]*len(fail_passes),
alpha=0.5, c='red', label='失败', s=60)
ax4.set_yticks([0, 1])
ax4.set_yticklabels(['失败', '成功'])
ax4.set_xlabel('传球距离 (米)')
ax4.set_title('传球距离与成功率关系')
ax4.legend()
plt.tight_layout()
plt.show()
return fig
# 4. 高级分析:球员表现排名
def advanced_player_analysis(attacking_third_passes):
"""高级球员分析"""
print("\n" + "=" * 60)
print("高级球员分析")
print("=" * 60)
# 球员综合评分
player_stats = attacking_third_passes.groupby('player_name').agg({
'pass_success': ['sum', 'count', 'mean'],
'pass_distance': 'mean'
}).round(2)
player_stats.columns = ['成功次数', '总传球数', '成功率', '平均距离']
player_stats['成功率'] = player_stats['成功率'] * 100
# 计算综合评分(自定义公式)
player_stats['综合评分'] = (
player_stats['成功率'] * 0.6 +
(player_stats['成功次数'] / player_stats['成功次数'].max()) * 100 * 0.4
)
# 排序
player_rank = player_stats.sort_values('综合评分', ascending=False).head(5)
print("\n🏆 最佳球员TOP 5:")
print(player_rank)
return player_rank
# 5. 时间序列分析
def time_series_analysis(attacking_third_passes):
"""时间序列分析"""
print("\n" + "=" * 60)
print("时间序列分析")
print("=" * 60)
# 按比赛阶段分析
attacking_third_passes['比赛阶段'] = pd.cut(
attacking_third_passes['timestamp'].dt.hour,
bins=[0, 45, 90],
labels=['上半场', '下半场']
)
stage_stats = attacking_third_passes.groupby('比赛阶段')['pass_success'].mean() * 100
print("\n📈 比赛阶段分析:")
print(stage_stats.round(2))
return stage_stats
# 6. 导出报告
def export_report(attacking_third_passes, filename='attacking_third_analysis.csv'):
"""导出分析报告"""
# 准备报告数据
report_data = attacking_third_passes[['player_name', 'match_id', 'pass_type',
'pass_direction', 'pressure_level',
'pass_success', 'pass_distance']]
report_data['is_attacking_third'] = True
# 添加其他区域的数据
all_passes = create_sample_data()
non_attacking_third = all_passes[~all_passes['is_attacking_third']]
non_attacking_third_report = non_attacking_third[['player_name', 'match_id', 'pass_type',
'pass_direction', 'pressure_level',
'pass_success', 'pass_distance']].copy()
non_attacking_third_report['is_attacking_third'] = False
# 合并数据
full_report = pd.concat([report_data, non_attacking_third_report])
# 保存到CSV
full_report.to_csv(filename, index=False, encoding='utf-8-sig')
print(f"\n✅ 报告已保存到 {filename}")
return full_report
# 主程序
if __name__ == "__main__":
print("🔍 开始足球传球数据分析...")
# 创建数据
df = create_sample_data()
# 数据分析
attacking_third_passes = analyze_attacking_third_passes(df)
# 可视化
fig = visualize_analysis(attacking_third_passes, df)
# 高级分析
player_rank = advanced_player_analysis(attacking_third_passes)
# 时间序列分析
stage_stats = time_series_analysis(attacking_third_passes)
# 导出报告
report = export_report(attacking_third_passes)
print("\n" + "=" * 60)
print("分析完成!")
print("=" * 60)
关键分析指标
这个案例涵盖了以下核心分析维度:
基础统计
- 进攻三区传球总次数和成功率
- 不同传球类型的成功率(短传、长传、直塞等)
情境分析
- 传球方向(向前、横向、向后)
- 压力等级对成功率的影响
- 传球距离与成功率的关系
球员分析
- 球员个人成功率排名
- 综合评分系统(成功率+传球次数加权)
比赛分析
- 不同比赛的表现对比
- 上下半场的表现差异
案例中包含4个核心图表:
- 区域对比图:进攻三区 vs 非进攻三区成功率对比
- 传球类型分析:不同传球方式的成功率
- 压力等级分布:不同压力下的成败占比
- 距离散点图:传球距离与成功与否的关系
扩展建议
如果需要更深入的分析,可以:
# 扩展1:分析对手压力下的表现
def pressure_analysis(df):
"""分析高压下的表现"""
high_pressure_data = df[(df['is_attacking_third']) & (df['pressure_level'] == '高')]
return high_pressure_data.groupby('player_name')['pass_success'].mean().sort_values(ascending=False)
# 扩展2:动态成功率趋势
def dynamic_success_rate(df):
"""计算移动平均成功率"""
df['success_rate'] = df['pass_success'].rolling(window=50).mean() * 100
return df[['timestamp', 'success_rate']].dropna()
这个案例提供了完整的进攻三区传球成功率分析框架,可以根据实际数据调整优化。