本文目录导读:

我来为您创建一个分析足球比赛中定位球得分占比的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 # 用来正常显示负号
# 创建示例数据
def create_sample_data():
"""创建模拟足球比赛数据"""
np.random.seed(42)
# 模拟100场比赛的数据
data = {
'match_id': range(1, 101),
'home_team': [f'主队_{i}' for i in range(1, 101)],
'away_team': [f'客队_{i}' for i in range(1, 101)],
'total_goals': np.random.poisson(2.5, 100) + np.random.randint(0, 2, 100),
'set_piece_goals': np.random.poisson(0.8, 100),
'open_play_goals': np.random.poisson(1.5, 100),
'penalty_goals': np.random.poisson(0.3, 100),
'free_kick_goals': np.random.poisson(0.2, 100),
'corner_goals': np.random.poisson(0.2, 100),
'throw_in_goals': np.random.poisson(0.1, 100)
}
df = pd.DataFrame(data)
# 确保总进球数等于各项进球之和(近似处理)
for i in range(len(df)):
total = df.loc[i, ['penalty_goals', 'free_kick_goals', 'corner_goals', 'throw_in_goals']].sum()
df.loc[i, 'set_piece_goals'] = total
df.loc[i, 'open_play_goals'] = max(0, df.loc[i, 'total_goals'] - total)
return df
def calculate_set_piece_stats(df):
"""计算定位球相关统计"""
stats = {}
# 总体统计
total_goals = df['total_goals'].sum()
total_set_piece = df['set_piece_goals'].sum()
total_open_play = df['open_play_goals'].sum()
stats['total_goals'] = total_goals
stats['total_set_piece'] = total_set_piece
stats['total_open_play'] = total_open_play
stats['set_piece_percentage'] = (total_set_piece / total_goals * 100) if total_goals > 0 else 0
stats['open_play_percentage'] = (total_open_play / total_goals * 100) if total_goals > 0 else 0
# 定位球细分类型
set_piece_types = {
'penalty': df['penalty_goals'].sum(),
'free_kick': df['free_kick_goals'].sum(),
'corner': df['corner_goals'].sum(),
'throw_in': df['throw_in_goals'].sum()
}
stats['set_piece_breakdown'] = set_piece_types
# 每场比赛的定位球统计
stats['avg_set_piece_per_match'] = df['set_piece_goals'].mean()
stats['avg_goals_per_match'] = df['total_goals'].mean()
return stats
def analyze_set_piece_trends(df):
"""分析定位球进球趋势"""
# 按比赛场次分组
df['match_group'] = pd.cut(df['match_id'], bins=10, labels=[f'第{i*10+1}-{(i+1)*10}场' for i in range(10)])
trends = df.groupby('match_group').agg({
'total_goals': 'sum',
'set_piece_goals': 'sum',
'open_play_goals': 'sum'
}).reset_index()
trends['set_piece_pct'] = (trends['set_piece_goals'] / trends['total_goals'] * 100).fillna(0)
return trends
def visualize_set_piece_stats(df, stats):
"""可视化定位球统计数据"""
fig, axes = plt.subplots(2, 2, figsize=(15, 12))
# 1. 定位球 vs 运动战进球对比
ax1 = axes[0, 0]
categories = ['定位球', '运动战']
values = [stats['total_set_piece'], stats['total_open_play']]
colors = ['#FF6B6B', '#4ECDC4']
bars = ax1.bar(categories, values, color=colors, alpha=0.7, edgecolor='black', linewidth=1)
ax1.set_title('定位球 vs 运动战进球总数对比', fontsize=14, fontweight='bold')
ax1.set_ylabel('进球数')
# 添加百分比标签
for bar, value in zip(bars, values):
height = bar.get_height()
pct = (value / stats['total_goals'] * 100)
ax1.text(bar.get_x() + bar.get_width()/2., height, f'{value}个\n({pct:.1f}%)',
ha='center', va='bottom', fontweight='bold')
# 2. 定位球类型细分饼图
ax2 = axes[0, 1]
set_piece_breakdown = stats['set_piece_breakdown']
labels = list(set_piece_breakdown.keys())
sizes = list(set_piece_breakdown.values())
explode = (0.1, 0, 0, 0) # 突出显示点球
colors_pie = ['#FF9999', '#66B2FF', '#99FF99', '#FFCC99']
wedges, texts, autotexts = ax2.pie(sizes, labels=labels, autopct='%1.1f%%',
explode=explode, colors=colors_pie,
startangle=90, shadow=True)
# 增强饼图文本显示
for text in texts:
text.set_fontsize(12)
text.set_fontweight('bold')
for autotext in autotexts:
autotext.set_color('white')
autotext.set_fontweight('bold')
ax2.set_title('定位球得分类型细分', fontsize=14, fontweight='bold')
# 3. 每场平均进球数
ax3 = axes[1, 0]
metrics = ['每场总进球', '每场定位球进球', '每场运动战进球']
avg_values = [
stats['avg_goals_per_match'],
stats['avg_set_piece_per_match'],
stats['avg_goals_per_match'] - stats['avg_set_piece_per_match']
]
bar_colors = ['#4ECDC4', '#FF6B6B', '#45B7D1']
bars3 = ax3.bar(metrics, avg_values, color=bar_colors, alpha=0.7, edgecolor='black', linewidth=1)
ax3.set_title('每场比赛平均进球数', fontsize=14, fontweight='bold')
ax3.set_ylabel('平均进球数')
for bar, value in zip(bars3, avg_values):
height = bar.get_height()
ax3.text(bar.get_x() + bar.get_width()/2., height, f'{value:.2f}',
ha='center', va='bottom', fontweight='bold')
# 4. 定位球占比趋势
ax4 = axes[1, 1]
trends = analyze_set_piece_trends(df)
x = range(len(trends))
ax4.plot(x, trends['set_piece_pct'], marker='o', color='#FF6B6B', linewidth=2, label='定位球占比')
ax4.axhline(y=stats['set_piece_percentage'], color='gray', linestyle='--', alpha=0.7,
label=f'总体平均: {stats["set_piece_percentage"]:.1f}%')
ax4.set_title('定位球进球占比趋势(按比赛分组)', fontsize=14, fontweight='bold')
ax4.set_xlabel('比赛场次分组')
ax4.set_ylabel('定位球占比 (%)')
ax4.set_xticks(x)
ax4.set_xticklabels(trends['match_group'], rotation=45, ha='right')
ax4.legend()
plt.tight_layout()
plt.show()
def generate_detailed_report(stats, trends):
"""生成详细的统计分析报告"""
report = []
report.append("=" * 60)
report.append(" 足球定位球得分统计报告")
report.append("=" * 60)
report.append(f"\n1. 总览统计")
report.append(f" - 总进球数: {stats['total_goals']} 个")
report.append(f" - 定位球进球: {stats['total_set_piece']} 个")
report.append(f" - 运动战进球: {stats['total_open_play']} 个")
report.append(f" - 定位球占比: {stats['set_piece_percentage']:.1f}%")
report.append(f" - 运动战占比: {stats['open_play_percentage']:.1f}%")
report.append(f"\n2. 定位球类型细分")
set_piece_breakdown = stats['set_piece_breakdown']
total_sp = sum(set_piece_breakdown.values())
type_names = {
'penalty': '点球',
'free_kick': '任意球',
'corner': '角球',
'throw_in': '界外球'
}
for key, value in set_piece_breakdown.items():
pct = (value / total_sp * 100) if total_sp > 0 else 0
report.append(f" - {type_names[key]}: {value} 个 ({pct:.1f}% 占定位球)")
report.append(f"\n3. 每场比赛平均数据")
report.append(f" - 平均每场总进球: {stats['avg_goals_per_match']:.2f} 个")
report.append(f" - 平均每场定位球进球: {stats['avg_set_piece_per_match']:.2f} 个")
report.append(f" - 平均每场运动战进球: {stats['avg_goals_per_match'] - stats['avg_set_piece_per_match']:.2f} 个")
report.append(f"\n4. 趋势分析")
if len(trends) > 0:
first_pct = trends.iloc[0]['set_piece_pct']
last_pct = trends.iloc[-1]['set_piece_pct']
change = last_pct - first_pct
if change > 0:
report.append(f" - 定位球占比呈现上升趋势,增长 {change:.1f}%")
elif change < 0:
report.append(f" - 定位球占比呈现下降趋势,下降 {abs(change):.1f}%")
else:
report.append(f" - 定位球占比保持稳定")
report.append("\n5. 结论与建议")
if stats['set_piece_percentage'] > 35:
report.append(" - 该球队/联赛定位球效率较高,进攻端定位球是重要得分手段")
elif stats['set_piece_percentage'] > 25:
report.append(" - 定位球得分占比适中,是进攻的重要组成部分")
else:
report.append(" - 定位球得分占比较低,可能需要加强定位球战术训练")
return "\n".join(report)
# 主程序
def main():
"""主函数"""
print("正在生成足球定位球得分分析报告...\n")
# 1. 创建示例数据
df = create_sample_data()
# 2. 计算统计指标
stats = calculate_set_piece_stats(df)
# 3. 分析趋势
trends = analyze_set_piece_trends(df)
# 4. 可视化展示
visualize_set_piece_stats(df, stats)
# 5. 生成详细报告
report = generate_detailed_report(stats, trends)
print(report)
# 6. 导出数据(可选)
df.to_csv('football_match_data.csv', index=False, encoding='utf-8-sig')
print("\n数据已保存至 football_match_data.csv")
return df, stats, trends
# 运行主程序
if __name__ == "__main__":
df, stats, trends = main()
扩展功能:使用真实数据
如果需要分析真实数据,可以使用以下方式:
def load_real_data(file_path):
"""从CSV文件加载真实比赛数据"""
df = pd.read_csv(file_path)
# 需要包含的列
required_columns = [
'match_id', 'total_goals', 'set_piece_goals',
'open_play_goals', 'penalty_goals', 'free_kick_goals',
'corner_goals', 'throw_in_goals'
]
# 检查并选择需要的列
available_columns = [col for col in required_columns if col in df.columns]
return df[available_columns]
# 使用示例
# df_real = load_real_data('your_match_data.csv')
# stats_real = calculate_set_piece_stats(df_real)
# print(f"真实数据定位球占比: {stats_real['set_piece_percentage']:.1f}%")
输出结果示例
程序会生成:
- 可视化图表:包括对比柱状图、饼图、趋势折线图等
- 文本统计报告:详细展示各类统计指标
- 数据文件:可导出的CSV格式数据
运行这个程序,您将得到完整的定位球得分占比分析,包括不同类型定位球(点球、任意球、角球等)的具体占比,以及随时间变化的趋势分析。