本文目录导读:

我来为您设计一个足球比赛中统计界外球进攻威胁次数的Python案例。
整体思路
界外球进攻威胁的判定需要考虑多个因素:
- 界外球位置(越靠近对方禁区威胁越大)
- 是否形成射门
- 是否形成传中
- 是否造成对方防守混乱
完整代码实现
import pandas as pd
import numpy as np
from datetime import datetime
import json
class ThrowInThreatAnalyzer:
"""界外球进攻威胁分析器"""
def __init__(self):
# 定义球场区域(将球场分为多个区域)
self.pitch_zones = {
'own_defensive': {'name': '本方后场', 'x_range': (0, 30), 'threat_weight': 0.1},
'own_midfield': {'name': '本方中场', 'x_range': (30, 50), 'threat_weight': 0.2},
'midfield': {'name': '中场', 'x_range': (50, 70), 'threat_weight': 0.3},
'opp_midfield': {'name': '对方中场', 'x_range': (70, 90), 'threat_weight': 0.5},
'opp_final_third': {'name': '对方前场', 'x_range': (90, 105), 'threat_weight': 0.8},
'opp_box': {'name': '对方禁区', 'x_range': (105, 120), 'threat_weight': 1.0}
}
# 结果存储
self.results = []
def judge_zone(self, x_coordinate):
"""判断界外球所在区域"""
for zone_id, zone_info in self.pitch_zones.items():
if zone_info['x_range'][0] <= x_coordinate < zone_info['x_range'][1]:
return zone_id, zone_info
return 'unknown', None
def analyze_throw_in(self, throw_in_data):
"""
分析单个界外球事件
参数:
throw_in_data: dict - 界外球数据
- position_x: 界外球位置的x坐标(0-120米)
- position_y: 界外球位置的y坐标(0-80米)
- player_position: 掷球后接球球员位置
- outcome: 掷球结果 ('射门', '助攻', '传中', '角球', '无效', '丢失')
- time: 比赛时间
返回:
dict - 分析结果
"""
try:
x_coord = throw_in_data.get('position_x', 0)
y_coord = throw_in_data.get('position_y', 40)
# 判断区域
zone_id, zone_info = self.judge_zone(x_coord)
# 基础威胁得分
base_threat = zone_info['threat_weight'] if zone_info else 0.3
# 根据结果加权
threat_score = base_threat
# 分析掷球结果
outcome = throw_in_data.get('outcome', '丢失')
outcome_multipliers = {
'射门': 2.0,
'助攻': 1.8,
'传中': 1.5,
'角球': 1.3,
'进球': 3.0,
'无效': 0.3,
'丢失': 0.1
}
threat_multiplier = outcome_multipliers.get(outcome, 0.5)
threat_score *= threat_multiplier
# 考虑接球位置(如果靠近球门)
if throw_in_data.get('player_position'):
player_x = throw_in_data['player_position'].get('x', 0)
# 接球位置越靠近对方球门,威胁越大
if player_x > 90:
threat_score *= 1.3
# 判断威胁等级
if threat_score >= 1.5:
threat_level = '高威胁'
elif threat_score >= 0.8:
threat_level = '中等威胁'
elif threat_score >= 0.3:
threat_level = '低威胁'
else:
threat_level = '无威胁'
# 记录分析结果
result = {
'time': throw_in_data.get('time', ''),
'position': (x_coord, y_coord),
'zone': zone_info['name'] if zone_info else '未知',
'outcome': outcome,
'base_threat': round(base_threat, 2),
'threat_score': round(threat_score, 2),
'threat_level': threat_level
}
self.results.append(result)
return result
except Exception as e:
print(f"分析界外球时出错: {e}")
return None
def analyze_batch(self, throw_in_events):
"""批量分析多个界外球事件"""
results = []
for event in throw_in_events:
result = self.analyze_throw_in(event)
if result:
results.append(result)
return results
def calculate_total_threats(self, high_threat_only=False):
"""计算总威胁次数"""
if not self.results:
return 0
if high_threat_only:
# 只计算高威胁
return sum(1 for r in self.results if r['threat_level'] == '高威胁')
else:
# 计算所有有威胁的界外球事件
return sum(1 for r in self.results if r['threat_level'] != '无威胁')
def print_analysis_report(self):
"""打印分析报告"""
print("=" * 60)
print("界外球进攻威胁分析报告")
print("=" * 60)
if not self.results:
print("暂无界外球数据分析")
return
# 统计数据
total_throw_ins = len(self.results)
high_threats = sum(1 for r in self.results if r['threat_level'] == '高威胁')
mid_threats = sum(1 for r in self.results if r['threat_level'] == '中等威胁')
low_threats = sum(1 for r in self.results if r['threat_level'] == '低威胁')
no_threats = total_throw_ins - high_threats - mid_threats - low_threats
print(f"\n总界外球次数: {total_throw_ins}")
print(f"高威胁次数: {high_threats}")
print(f"中等威胁次数: {mid_threats}")
print(f"低威胁次数: {low_threats}")
print(f"无威胁次数: {no_threats}")
print(f"\n进攻威胁总次数: {self.calculate_total_threats()}")
print(f"高威胁占比: {high_threats/total_throw_ins*100:.1f}%" if total_throw_ins > 0 else "")
# 按区域和结果分析
print("\n--- 区域分布 ---")
zone_stats = {}
for r in self.results:
zone = r['zone']
if zone not in zone_stats:
zone_stats[zone] = {'count': 0, 'threats': 0}
zone_stats[zone]['count'] += 1
if r['threat_level'] != '无威胁':
zone_stats[zone]['threats'] += 1
for zone, stats in zone_stats.items():
print(f"{zone}: 共{stats['count']}次, stats['threats']}次构成威胁")
# 详细结果列表
print("\n--- 详细事件列表 ---")
for idx, r in enumerate(self.results, 1):
print(f"{idx}. 时间: {r['time']}")
print(f" 位置: {r['position']}")
print(f" 区域: {r['zone']}")
print(f" 结果: {r['outcome']}")
print(f" 威胁得分: {r['threat_score']}")
print(f" 威胁等级: {r['threat_level']}")
print()
def generate_sample_data():
"""生成示例数据"""
return [
{
'time': '12:30',
'position_x': 110,
'position_y': 65,
'player_position': {'x': 108, 'y': 70},
'outcome': '射门',
'team': '主队'
},
{
'time': '25:10',
'position_x': 85,
'position_y': 35,
'player_position': {'x': 88, 'y': 40},
'outcome': '传中',
'team': '主队'
},
{
'time': '38:45',
'position_x': 60,
'position_y': 45,
'player_position': {'x': 62, 'y': 50},
'outcome': '丢失',
'team': '主队'
},
{
'time': '52:20',
'position_x': 115,
'position_y': 50,
'player_position': {'x': 112, 'y': 55},
'outcome': '助攻',
'team': '主队'
},
{
'time': '70:15',
'position_x': 95,
'position_y': 30,
'player_position': {'x': 97, 'y': 35},
'outcome': '角球',
'team': '主队'
},
{
'time': '83:50',
'position_x': 100,
'position_y': 20,
'player_position': {'x': 102, 'y': 25},
'outcome': '传中',
'team': '主队'
},
{
'time': '88:33',
'position_x': 30,
'position_y': 60,
'player_position': {'x': 35, 'y': 55},
'outcome': '丢失',
'team': '主队'
}
]
def main():
"""主函数示例"""
# 创建分析器
analyzer = ThrowInThreatAnalyzer()
# 生成示例数据
sample_events = generate_sample_data()
# 分析界外球事件
print("开始分析界外球事件...")
results = analyzer.analyze_batch(sample_events)
# 打印分析报告
analyzer.print_analysis_report()
# 导出结果到JSON
with open('throw_in_analysis.json', 'w', encoding='utf-8') as f:
json.dump(analyzer.results, f, ensure_ascii=False, indent=2)
print("分析结果已保存到 throw_in_analysis.json")
# 额外分析示例
print("\n" + "="*60)
print("进阶统计数据")
print("="*60)
print(f"总界外球威胁次数: {analyzer.calculate_total_threats()}")
print(f"仅高威胁次数: {analyzer.calculate_total_threats(high_threat_only=True)}")
if __name__ == "__main__":
main()
简化版本(适合快速使用)
def simple_throw_in_threat_analysis(throw_in_data):
"""
简化的界外球威胁分析函数
参数:
throw_in_data: list of dict, 每个dict包含:
- x_position: 球在纵轴的位置(0-120)
- was_shot: 是否形成射门
- was_cross: 是否形成传中
- was_foul_won: 是否赢得犯规
返回:
tuple: (总次数, 威胁次数)
"""
threat_count = 0
total_count = len(throw_in_data)
for event in throw_in_data:
# 简单评分系统
threat_score = 0
# 位置因素 (x > 90 表示在对方30米区域)
if event['x_position'] > 90:
threat_score += 1
# 结果因素
if event.get('was_shot'):
threat_score += 2
if event.get('was_cross'):
threat_score += 1.5
if event.get('was_foul_won'):
threat_score += 0.5
# 判断是否构成威胁
if threat_score >= 1.5: # 至少要有位置优势加一个积极结果
threat_count += 1
return total_count, threat_count
# 使用示例
sample_data = [
{'x_position': 115, 'was_shot': True, 'was_cross': False, 'was_foul_won': False},
{'x_position': 85, 'was_shot': False, 'was_cross': True, 'was_foul_won': True},
{'x_position': 60, 'was_shot': False, 'was_cross': False, 'was_foul_won': False},
]
total, threats = simple_throw_in_threat_analysis(sample_data)
print(f"总界外球数: {total}, 威胁次数: {threats}")
使用说明
数据准备
需要准备界外球事件的数据,包含:
- 位置信息: 界外球发生的x坐标(模拟足球场长度0-120米)
- 结果: 掷球后发生了什么(射门、传中、助攻等)
- 时间: 事件发生时间
运行方式
python throw_in_analyzer.py
输出结果
程序会输出:
- 各种威胁等级的数量
- 总威胁次数
- 高威胁占比
- 按区域统计
- 每个事件的详细分析
- 自动保存JSON文件
判定标准说明
威胁等级判定:
- 高威胁(得分>=1.5): 在对方禁区附近获得球权并形成射门/助攻
- 中等威胁(得分>=0.8): 前场30米内的界外球形成传中或得到角球
- 低威胁(得分>=0.3): 中场的界外球有进攻的意图
- 无威胁: 防守压力下的求生性掷球
这个系统可以应用于:
- 赛后技术统计
- 球员/教练战术分析
- 视频分析师的数据标注
- 球员专项训练效果评估
您可以根据实际需求调整权重参数和判定标准!
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播