本文目录导读:

我来为您设计一个统计界外球进攻威胁次数的Python案例,这个案例会模拟足球比赛中界外球的情况。
完整案例实现
import random
import numpy as np
from dataclasses import dataclass
from typing import List, Dict, Tuple
import matplotlib.pyplot as plt
from collections import defaultdict
@dataclass
class ThrowIn:
"""界外球事件类"""
time: int # 比赛时间
team: str # 球队
x_position: float # 界外球位置x坐标(0-105米)
y_position: float # 界外球位置y坐标(0-68米)
throw_type: str # 界外球类型(长距离、短距离、快速、常规)
target_area: str # 投掷目标区域
resulted_in_chance: bool # 是否形成进攻威胁
chance_type: str # 威胁类型(射门、角球、传中、任意球等)
class ThrowInAnalyzer:
"""界外球威胁分析器"""
def __init__(self, team_name: str):
self.team_name = team_name
self.throw_ins = []
def simulate_match_throw_ins(self, num_throws: int = 30):
"""模拟一场比赛的界外球事件"""
throw_types = ['长距离', '短距离', '快速', '常规']
target_areas = ['前场中路', '前场边路', '中场区域', '后场区域']
chance_types = ['射门机会', '角球', '传中', '头球机会', '任意球', '暂无']
for i in range(num_throws):
# 随机生成界外球数据
x_pos = random.uniform(0, 105)
y_pos = random.uniform(0, 68)
# 判断是否形成威胁(基于位置和类型)
is_chance = False
if x_pos > 65: # 前场区域
is_chance = random.random() < 0.4
elif x_pos > 50:
is_chance = random.random() < 0.15
chance_type = random.choice(chance_types[:-1]) if is_chance else '暂无'
throw = ThrowIn(
time=i * 3, # 模拟每3分钟一个界外球
team=self.team_name,
x_position=x_pos,
y_position=y_pos,
throw_type=random.choice(throw_types),
target_area=random.choice(target_areas),
resulted_in_chance=is_chance,
chance_type=chance_type
)
self.throw_ins.append(throw)
return self.throw_ins
def analyze_threat_level(self) -> Dict[str, Dict]:
"""分析界外球威胁等级"""
analysis = {
'high_risk': {'count': 0, 'events': []}, # 前场界外球且形成威胁
'medium_risk': {'count': 0, 'events': []}, # 前场界外球但未形成威胁
'low_risk': {'count': 0, 'events': []} # 后场界外球
}
for throw in self.throw_ins:
if throw.x_position > 65 and throw.resulted_in_chance:
analysis['high_risk']['count'] += 1
analysis['high_risk']['events'].append(throw)
elif throw.x_position > 65:
analysis['medium_risk']['count'] += 1
analysis['medium_risk']['events'].append(throw)
else:
analysis['low_risk']['count'] += 1
analysis['low_risk']['events'].append(throw)
return analysis
def calculate_threat_indicator(self) -> float:
"""计算威胁指数(0-100)"""
if not self.throw_ins:
return 0
total_throws = len(self.throw_ins)
dangerous_throws = sum(1 for t in self.throw_ins if t.x_position > 65 and t.resulted_in_chance)
medium_throws = sum(1 for t in self.throw_ins if t.x_position > 65 and not t.resulted_in_chance)
# 计算加权威胁指数
threat_score = (dangerous_throws * 1.5 + medium_throws * 1.0) / total_throws * 100
return min(threat_score, 100)
def analyze_throw_patterns(self) -> Dict:
"""分析界外球模式"""
patterns = {
'by_type': defaultdict(int),
'by_location': defaultdict(int),
'success_rate': 0
}
# 统计类型分布
for throw in self.throw_ins:
patterns['by_type'][throw.throw_type] += 1
# 位置分布(按区域划分)
if throw.x_position > 75:
patterns['by_location']['极有威胁区域'] += 1
elif throw.x_position > 65:
patterns['by_location']['进攻三区'] += 1
elif throw.x_position > 50:
patterns['by_location']['中场进攻区域'] += 1
else:
patterns['by_location']['防守区域'] += 1
# 成功率
total_throws = len(self.throw_ins)
successful = sum(1 for t in self.throw_ins if t.resulted_in_chance)
patterns['success_rate'] = successful / total_throws * 100 if total_throws > 0 else 0
return patterns
def get_top_threat_locations(self, top_n: int = 5) -> List[Tuple]:
"""获取威胁最大的区域"""
# 将球场网格化
grid = defaultdict(int)
for throw in self.throw_ins:
if throw.resulted_in_chance:
grid_x = int(throw.x_position // 10) * 10
grid_y = int(throw.y_position // 10) * 10
grid[(grid_x, grid_y)] += 1
sorted_locations = sorted(grid.items(), key=lambda x: x[1], reverse=True)
return sorted_locations[:top_n]
def visualize_threat_map(self):
"""可视化威胁地图"""
plt.figure(figsize=(12, 8))
# 绘制球场
plt.xlim(-5, 110)
plt.ylim(-5, 73)
plt.gca().set_facecolor('lightgreen')
# 绘制界外球位置
for throw in self.throw_ins:
if throw.resulted_in_chance:
color = 'red'
marker = 'o'
size = 80
elif throw.x_position > 65:
color = 'orange'
marker = 's'
size = 60
else:
color = 'blue'
marker = 's'
size = 40
plt.scatter(throw.x_position, throw.y_position, c=color, s=size, alpha=0.7, marker=marker)
# 绘制球场线
plt.plot([0, 0], [0, 68], 'k-', linewidth=2)
plt.plot([105, 105], [0, 68], 'k-', linewidth=2)
plt.plot([0, 105], [0, 0], 'k-', linewidth=2)
plt.plot([0, 105], [68, 68], 'k-', linewidth=2)
# 中线和禁区
plt.plot([52.5, 52.5], [0, 68], 'k--')
plt.plot([16.5, 16.5], [0, 68], 'k-')
plt.plot([88.5, 88.5], [0, 68], 'k-')
plt.title(f'{self.team_name} 界外球威胁分布图')
plt.xlabel('球门方向 (米)')
plt.ylabel('场地宽度 (米)')
plt.legend(['有威胁界外球', '前场界外球', '后场界外球'], loc='upper right')
plt.grid(True, alpha=0.3)
plt.show()
def generate_report(self) -> str:
"""生成分析报告"""
total_count = len(self.throw_ins)
threat_count = sum(1 for t in self.throw_ins if t.resulted_in_chance)
analysis = self.analyze_threat_level()
patterns = self.analyze_throw_patterns()
threat_index = self.calculate_threat_indicator()
report = f"""
{'='*50}
{self.team_name} 界外球威胁分析报告
{'='*50}
基础数据:
- 总界外球次数:{total_count}
- 形成威胁次数:{threat_count} ({threat_count/total_count*100:.1f}%)
- 威胁等级分类:
* 高危威胁:{analysis['high_risk']['count']}次
* 中危威胁:{analysis['medium_risk']['count']}次
* 低危威胁:{analysis['low_risk']['count']}次
威胁指数:{threat_index:.1f}/100
模式分析:
- 成功率:{patterns['success_rate']:.1f}%
- 类型分布:{dict(patterns['by_type'])}
- 位置分布:{dict(patterns['by_location'])}
最威胁区域(前5):
"""
top_locations = self.get_top_threat_locations()
for i, (loc, count) in enumerate(top_locations, 1):
report += f" {i}. 区域({loc[0]}-{loc[0]+10}m, {loc[1]}-{loc[1]+10}m): {count}次威胁\n"
report += "\n建议:"
if threat_index > 70:
report += "\n- 进攻质量很高,应保持现有策略"
report += "\n- 可增加界外球战术多样性"
elif threat_index > 40:
report += "\n- 具有一定的进攻威胁,可加强前场界外球配合"
report += "\n- 考虑训练特定界外球战术"
else:
report += "\n- 界外球威胁较低,需要加强战术设计"
report += "\n- 建议增加前场界外球次数"
return report
# 使用示例
def main():
# 创建分析器
analyzer = ThrowInAnalyzer("Team A")
# 模拟比赛数据
print("模拟比赛数据...")
analyzer.simulate_match_throw_ins(35)
# 分析威胁
print("\n分析威胁等级:")
analysis = analyzer.analyze_threat_level()
for risk_level, data in analysis.items():
print(f" {risk_level}: {data['count']}次")
# 计算威胁指数
threat_index = analyzer.calculate_threat_indicator()
print(f"\n威胁指数: {threat_index:.1f}/100")
# 分析模式
print("\n分析模式:")
patterns = analyzer.analyze_throw_patterns()
print(f" 成功率: {patterns['success_rate']:.1f}%")
print(f" 类型分布: {dict(patterns['by_type'])}")
# 生成报告
print("\n生成报告:")
report = analyzer.generate_report()
print(report)
# 可视化(如需显示图表)
# analyzer.visualize_threat_map()
if __name__ == "__main__":
main()
进阶版本:实战数据导入接口
import pandas as pd
import json
from datetime import datetime
class AdvancedThrowInAnalyzer(ThrowInAnalyzer):
"""进阶版界外球分析器,支持数据导入"""
def import_from_dataframe(self, df: pd.DataFrame, team_name: str):
"""从DataFrame导入数据"""
self.team_name = team_name
self.throw_ins = []
for _, row in df.iterrows():
throw = ThrowIn(
time=row['time'],
team=team_name,
x_position=row['x_position'],
y_position=row['y_position'],
throw_type=row['throw_type'],
target_area=row['target_area'],
resulted_in_chance=row['resulted_in_chance'],
chance_type=row['chance_type'] if 'chance_type' in row else '暂无'
)
self.throw_ins.append(throw)
def export_to_json(self, filename: str):
"""导出数据到JSON"""
data = []
for t in self.throw_ins:
data.append({
'time': t.time,
'team': t.team,
'x_position': t.x_position,
'y_position': t.y_position,
'throw_type': t.throw_type,
'target_area': t.target_area,
'resulted_in_chance': t.resulted_in_chance,
'chance_type': t.chance_type
})
with open(filename, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
def load_from_json(self, filename: str, team_name: str):
"""从JSON加载数据"""
with open(filename, 'r', encoding='utf-8') as f:
data = json.load(f)
self.team_name = team_name
self.throw_ins = []
for item in data:
throw = ThrowIn(**item)
self.throw_ins.append(throw)
# 使用进阶功能
def advanced_usage():
# 创建示例数据框
sample_data = pd.DataFrame({
'time': [10, 23, 45, 67, 89],
'x_position': [70.5, 55.2, 80.1, 45.7, 90.3],
'y_position': [15.2, 30.5, 25.8, 40.1, 20.4],
'throw_type': ['长距离', '短距离', '长距离', '快速', '常规'],
'target_area': ['前场中路', '中场区域', '前场边路', '后场区域', '前场中路'],
'resulted_in_chance': [True, False, True, False, True],
'chance_type': ['射门机会', '暂无', '角球', '暂无', '传中']
})
advanced = AdvancedThrowInAnalyzer("Team B")
advanced.import_from_dataframe(sample_data, "Team B")
# 导出数据
advanced.export_to_json("throw_ins_data.json")
# 加载数据
loaded_analyzer = AdvancedThrowInAnalyzer("Team B")
loaded_analyzer.load_from_json("throw_ins_data.json", "Team B")
print("数据导入导出功能演示完成!")
运行说明
-
环境要求:需要安装
numpy,matplotlib,pandaspip install numpy matplotlib pandas
-
主要功能:
- 模拟比赛界外球数据
- 分析界外球威胁等级
- 计算威胁指数
- 识别高威胁区域
- 可视化威胁分布
- 生成分析报告
这个系统可以用于:
- 战术分析
- 比赛复盘
- 对手研究
- 训练针对性提高