本文目录导读:

我来为您设计一个统计足球界外球进攻威胁次数的Python案例,这个案例会包含数据模拟、分析和可视化。
完整实现代码
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime, timedelta
import random
# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
class ThrowInThreatAnalyzer:
"""界外球进攻威胁分析器"""
def __init__(self):
self.throw_in_data = []
self.threat_events = []
def simulate_throw_in_data(self, num_events=100):
"""模拟界外球数据"""
teams = ['主队', '客队']
zones = ['进攻三区', '中场区域', '防守三区']
players = [f'球员{i:02d}' for i in range(1, 12)]
for i in range(num_events):
event = {
'事件编号': f'TI-{i+1:04d}',
'时间': f'{random.randint(1, 90)}:{(random.randint(0, 59)):02d}',
'队伍': random.choice(teams),
'执行球员': random.choice(players),
'区域': random.choice(zones),
'距离球门': random.randint(5, 40), # 米
'传球成功率': random.uniform(0.5, 1.0),
'接球球员位置': random.choice(['边路', '中路', '禁区']),
'防守压力': random.choice(['高', '中', '低']),
'是否有队友接应': random.choice([True, False])
}
# 计算威胁分数
event['威胁分数'] = self.calculate_threat_score(event)
event['是否构成威胁'] = event['威胁分数'] >= 0.6
self.throw_in_data.append(event)
return pd.DataFrame(self.throw_in_data)
def calculate_threat_score(self, event):
"""计算界外球的威胁分数"""
score = 0
# 区域权重
zone_weights = {
'进攻三区': 0.5,
'中场区域': 0.3,
'防守三区': 0.1
}
score += zone_weights[event['区域']]
# 距离球门权重(越近威胁越大)
distance_weight = max(0, 0.3 - event['距离球门']/100)
score += distance_weight
# 传球成功率权重
score += event['传球成功率'] * 0.15
# 接球位置权重
position_weights = {
'禁区': 0.2,
'中路': 0.15,
'边路': 0.1
}
score += position_weights[event['接球球员位置']]
# 防守压力影响(压力越小威胁越大)
pressure_weights = {
'低': 0.1,
'中': 0.05,
'高': 0.02
}
score += pressure_weights[event['防守压力']]
# 队友接应奖励
if event['是否有队友接应']:
score += 0.1
return min(1.0, score)
def analyze_threats(self, df):
"""分析威胁事件"""
results = {}
# 基础统计
results['总界外球次数'] = len(df)
results['威胁事件次数'] = len(df[df['是否构成威胁'] == True])
results['威胁比率'] = (results['威胁事件次数'] / results['总界外球次数']) * 100
# 按队伍统计
team_stats = df.groupby('队伍').agg({
'事件编号': 'count',
'是否构成威胁': lambda x: sum(x),
'威胁分数': 'mean'
}).rename(columns={
'事件编号': '总次数',
'是否构成威胁': '威胁次数',
'威胁分数': '平均威胁分数'
})
results['队伍统计'] = team_stats
# 按区域统计
zone_stats = df.groupby('区域').agg({
'事件编号': 'count',
'是否构成威胁': lambda x: sum(x),
'威胁分数': 'mean'
}).rename(columns={
'事件编号': '总次数',
'是否构成威胁': '威胁次数',
'威胁分数': '平均威胁分数'
})
results['区域统计'] = zone_stats
# 高威胁事件(得分前20%)
high_threshold = df['威胁分数'].quantile(0.8)
high_threats = df[df['威胁分数'] >= high_threshold]
results['高威胁事件'] = high_threats
results['高威胁阈值'] = high_threshold
# 时间分布
df['分钟'] = df['时间'].apply(lambda x: int(x.split(':')[0]))
time_stats = df.groupby(pd.cut(df['分钟'], bins=[0, 15, 30, 45, 60, 75, 90],
labels=['0-15', '16-30', '31-45', '46-60', '61-75', '76-90'])).agg({
'事件编号': 'count',
'是否构成威胁': lambda x: sum(x)
}).rename(columns={
'事件编号': '总次数',
'是否构成威胁': '威胁次数'
})
results['时间段统计'] = time_stats
return results
def visualize_results(self, df, results):
"""可视化分析结果"""
fig, axes = plt.subplots(2, 2, figsize=(15, 12))
# 1. 威胁比率饼图
ax1 = axes[0, 0]
threat_counts = df['是否构成威胁'].value_counts()
colors = ['#ff9999', '#66b3ff']
ax1.pie(threat_counts, labels=['威胁', '无威胁'], colors=colors,
autopct='%1.1f%%', startangle=90)
ax1.set_title('界外球威胁比率分布')
# 2. 区域威胁分析柱状图
ax2 = axes[0, 1]
zone_data = results['区域统计']
x = range(len(zone_data.index))
width = 0.35
ax2.bar([i - width/2 for i in x], zone_data['总次数'], width,
label='总次数', color='lightblue')
ax2.bar([i + width/2 for i in x], zone_data['威胁次数'], width,
label='威胁次数', color='coral')
ax2.set_xlabel('区域')
ax2.set_ylabel('次数')
ax2.set_title('不同区域的界外球威胁分析')
ax2.set_xticks(x)
ax2.set_xticklabels(zone_data.index)
ax2.legend()
# 3. 威胁分数分布直方图
ax3 = axes[1, 0]
ax3.hist(df['威胁分数'], bins=20, alpha=0.7, color='green', edgecolor='black')
ax3.axvline(results['高威胁阈值'], color='red', linestyle='--',
label=f'高威胁阈值: {results["高威胁阈值"]:.2f}')
ax3.set_xlabel('威胁分数')
ax3.set_ylabel('频次')
ax3.set_title('威胁分数分布')
ax3.legend()
# 4. 时间段威胁趋势图
ax4 = axes[1, 1]
time_data = results['时间段统计']
time_data.plot(kind='line', marker='o', ax=ax4)
ax4.set_xlabel('时间段')
ax4.set_ylabel('次数')
ax4.set_title('不同时间段的界外球威胁趋势')
ax4.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
def generate_report(self, df, results):
"""生成分析报告"""
print("=" * 50)
print("界外球进攻威胁分析报告")
print("=" * 50)
print(f"\n1. 总体统计")
print(f" - 总界外球次数: {results['总界外球次数']}")
print(f" - 威胁事件次数: {results['威胁事件次数']}")
print(f" - 威胁比率: {results['威胁比率']:.2f}%")
print("\n2. 队伍统计")
print(results['队伍统计'].to_string())
print("\n3. 区域统计")
print(results['区域统计'].to_string())
print("\n4. 时间段统计")
print(results['时间段统计'].to_string())
print(f"\n5. 高威胁事件 (阈值: {results['高威胁阈值']:.2f})")
high_threats = results['高威胁事件']
print(f" - 高威胁事件数量: {len(high_threats)}")
if len(high_threats) > 0:
print(" 前5个高威胁事件:")
print(high_threats[['时间', '队伍', '区域', '距离球门', '威胁分数']].head().to_string())
print("\n6. 建议和洞察")
insights = self.generate_insights(results)
for i, insight in enumerate(insights, 1):
print(f" {i}. {insight}")
def generate_insights(self, results):
"""生成分析洞察"""
insights = []
zone_data = results['区域统计']
# 最佳威胁区域
best_zone = zone_data['威胁次数'].idxmax()
insights.append(f"进攻三区是界外球威胁最大的区域,建议加强对该区域的防守")
# 队伍对比
team_data = results['队伍统计']
if len(team_data) >= 2:
better_team = team_data['威胁次数'].idxmax()
insights.append(f"{better_team}在界外球进攻上更具威胁性")
# 时间段洞察
time_data = results['时间段统计']
best_time = time_data['威胁次数'].idxmax()
insights.append(f"在{best_time}时间段的界外球威胁最多,需要注意该时段的防守")
return insights
# 主程序
def main():
# 创建分析器
analyzer = ThrowInThreatAnalyzer()
# 模拟数据
print("正在模拟界外球数据...")
df = analyzer.simulate_throw_in_data(num_events=200)
print(f"数据模拟完成,共 {len(df)} 次界外球")
# 分析数据
print("\n正在分析威胁数据...")
results = analyzer.analyze_threats(df)
# 生成报告
analyzer.generate_report(df, results)
# 可视化
print("\n正在生成可视化图表...")
analyzer.visualize_results(df, results)
# 保存数据
df.to_csv('throw_in_analysis.csv', index=False, encoding='utf-8-sig')
print("\n数据已保存至 'throw_in_analysis.csv'")
# 额外的深度分析
print("\n" + "=" * 50)
print("进阶分析")
print("=" * 50)
# 找出最佳界外球战术
print("\n最佳界外球条件分析:")
successful_throws = df[df['是否构成威胁'] == True]
if len(successful_throws) > 0:
best_conditions = {
'区域': successful_throws['区域'].mode()[0],
'接球位置': successful_throws['接球球员位置'].mode()[0],
'防守压力': successful_throws['防守压力'].mode()[0],
'队友接应': successful_throws['是否有队友接应'].mode()[0]
}
print(f" - 最佳界外球区域: {best_conditions['区域']}")
print(f" - 最佳接球位置: {best_conditions['接球位置']}")
print(f" - 低防守压力比例: {(successful_throws['防守压力']=='低').sum()/len(successful_throws)*100:.1f}%")
print(f" - 有队友接应比例: {successful_throws['是否有队友接应'].sum()/len(successful_throws)*100:.1f}%")
if __name__ == "__main__":
main()
核心功能说明
- 数据模拟:生成界外球事件的模拟数据
- 威胁评估:基于多因素计算威胁分数
- 统计分析:多维度分析威胁事件
- 可视化:直观展示分析结果
- 报告生成:自动生成分析报告和洞察
扩展建议
# 可以添加的扩展功能
def add_advanced_features(analyzer):
"""添加高级功能"""
# 1. 球员效率排名
def player_efficiency(df):
player_stats = df.groupby('执行球员').agg({
'事件编号': 'count',
'是否构成威胁': lambda x: sum(x),
'威胁分数': 'mean'
})
player_stats['效率'] = player_stats['威胁次数'] / player_stats['事件编号'] * 100
return player_stats.sort_values('效率', ascending=False)
# 2. 战术模式识别
def identify_patterns(df):
patterns = df.groupby(['区域', '接球球员位置', '防守压力']).agg({
'是否构成威胁': lambda x: sum(x),
'事件编号': 'count'
})
patterns['成功率'] = patterns['是否构成威胁'] / patterns['事件编号']
return patterns.nlargest(5, '成功率')
# 3. 时间序列分析
def time_series_analysis(df):
df['时间戳'] = pd.to_datetime(df['时间'], format='%M:%S')
df['分钟'] = df['时间戳'].dt.minute
rolling_mean = df.set_index('分钟')['威胁分数'].rolling(5).mean()
return rolling_mean
这个案例提供了完整的界外球威胁分析系统,可根据实际需求调整参数和功能。