本文目录导读:

我来帮你创建一个统计高位逼抢中夺回球权次数的Python案例,这个案例会模拟比赛数据并进行分析。
完整案例代码
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from dataclasses import dataclass
from typing import List, Dict, Tuple
import random
@dataclass
class BallRecovery:
"""球权恢复数据类"""
minute: int
player: str
zone: str
recovery_type: str
opponent_team: str
pressure_level: str
outcome: str
is_high_press: bool # 是否是高位逼抢
class HighPressAnalyzer:
"""高位逼抢球权恢复分析器"""
def __init__(self):
self.recoveries = []
self.high_press_count = 0
self.total_count = 0
def generate_match_data(self, num_events=100):
"""生成模拟比赛数据"""
players = ['张伟', '李强', '王浩', '刘洋', '陈晨',
'赵磊', '孙明', '周军', '吴刚', '郑凯']
zones = ['前场左路', '前场中路', '前场右路',
'中场左路', '中场中路', '中场右路',
'后场左路', '后场中路', '后场右路']
recovery_types = ['抢断', '拦截', '争顶', '解围']
outcomes = ['传球', '射门', '控球', '犯规', '出界']
self.recoveries = []
for _ in range(num_events):
minute = random.randint(1, 90)
player = random.choice(players)
zone = random.choice(zones)
recovery_type = random.choice(recovery_types)
outcome = random.choice(outcomes)
# 判断是否为高位逼抢(前场和中场区域)
is_high_press = zone.startswith(('前场', '中场'))
# 压力等级基于位置
if zone.startswith('前场'):
pressure_level = '高强度'
elif zone.startswith('中场'):
pressure_level = '中等强度' if random.random() < 0.5 else '高强度'
else:
pressure_level = '低强度'
recovery = BallRecovery(
minute=minute,
player=player,
zone=zone,
recovery_type=recovery_type,
opponent_team='对手队',
pressure_level=pressure_level,
outcome=outcome,
is_high_press=is_high_press
)
self.recoveries.append(recovery)
self.total_count += len(self.recoveries)
def count_high_press_recoveries(self) -> Dict:
"""统计高位逼抢夺回球权次数"""
# 筛选高位逼抢的球权恢复
high_press_recoveries = [r for r in self.recoveries if r.is_high_press]
self.high_press_count = len(high_press_recoveries)
return {
'total_recoveries': len(self.recoveries),
'high_press_recoveries': self.high_press_count,
'percentage': f"{self.high_press_count / len(self.recoveries) * 100:.1f}%"
}
def analyze_by_zone(self) -> pd.DataFrame:
"""按区域分析球权恢复"""
df = pd.DataFrame([vars(r) for r in self.recoveries])
# 分离前场、中场、后场
df['area'] = df['zone'].apply(lambda x: x[:2])
zone_stats = df.groupby(['area', 'is_high_press']).size().reset_index(name='count')
zone_pivot = zone_stats.pivot(index='area', columns='is_high_press', values='count')
zone_pivot = zone_pivot.fillna(0)
zone_pivot.columns = ['非高位逼抢', '高位逼抢']
zone_pivot['总计'] = zone_pivot.sum(axis=1)
zone_pivot['高位占比'] = zone_pivot['高位逼抢'] / zone_pivot['总计'] * 100
return zone_pivot
def analyze_by_player(self) -> pd.DataFrame:
"""按球员分析球权恢复"""
df = pd.DataFrame([vars(r) for r in self.recoveries])
high_press_df = df[df['is_high_press']]
player_stats = high_press_df.groupby('player').agg({
'minute': 'count',
'recovery_type': lambda x: ', '.join(x.unique())
}).rename(columns={'minute': '高位逼抢次数', 'recovery_type': '恢复方式'})
player_stats = player_stats.sort_values('高位逼抢次数', ascending=False)
return player_stats
def analyze_over_time(self) -> pd.DataFrame:
"""按时间分析球权恢复"""
df = pd.DataFrame([vars(r) for r in self.recoveries])
# 按15分钟分段
df['period'] = pd.cut(df['minute'], bins=[0, 15, 30, 45, 60, 75, 90],
labels=['0-15', '15-30', '30-45', '45-60', '60-75', '75-90'])
over_time = df[df['is_high_press']].groupby('period').size().reset_index(name='次数')
over_time['占比'] = over_time['次数'] / over_time['次数'].sum() * 100
return over_time
def visualize_results(self):
"""可视化统计结果"""
fig, axes = plt.subplots(2, 2, figsize=(15, 12))
# 1. 总体统计饼图
ax1 = axes[0, 0]
high_press = self.high_press_count
normal_press = self.total_count - high_press
ax1.pie([high_press, normal_press],
labels=['高位逼抢', '其他情况'],
autopct='%1.1f%%',
colors=['#FF6B6B', '#4ECDC4'],
explode=(0.05, 0))
ax1.set_title(f'总体球权恢复分布 (总次数: {self.total_count})')
# 2. 区域分析柱状图
ax2 = axes[0, 1]
zone_data = self.analyze_by_zone()
x = np.arange(len(zone_data.index))
width = 0.35
ax2.bar(x - width/2, zone_data['高位逼抢'], width, label='高位逼抢', color='#FF6B6B')
ax2.bar(x + width/2, zone_data['非高位逼抢'], width, label='非高位逼抢', color='#4ECDC4')
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]
player_data = self.analyze_by_player()
if not player_data.empty:
ax3.barh(player_data.head(5).index, player_data['高位逼抢次数'].head(5), color='#FF6B6B')
ax3.set_xlabel('次数')
ax3.set_title('高位逼抢球权恢复Top5球员')
ax3.invert_yaxis() # 让最多的在上面
# 4. 时间趋势图
ax4 = axes[1, 1]
time_data = self.analyze_over_time()
ax4.plot(time_data['period'], time_data['次数'], marker='o', linewidth=2, color='#FF6B6B')
ax4.fill_between(time_data['period'], time_data['次数'], alpha=0.3, color='#FF6B6B')
ax4.set_xlabel('比赛时间段')
ax4.set_ylabel('高位逼抢次数')
ax4.set_title('比赛不同阶段的高位逼抢球权恢复')
ax4.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
class MatchReporter:
"""生成比赛报告类"""
def __init__(self, analyzer: HighPressAnalyzer):
self.analyzer = analyzer
def generate_report(self) -> str:
"""生成分析报告"""
stats = self.analyzer.count_high_press_recoveries()
zone_data = self.analyzer.analyze_by_zone()
player_data = self.analyzer.analyze_by_player()
report = f"""
========== 高位逼抢球权恢复分析报告 ==========
【总体统计】
总球权恢复次数:{stats['total_recoveries']} 次
高位逼抢恢复:{stats['high_press_recoveries']} 次
占比:{stats['percentage']}
【区域分析】
{zone_data.to_string()}
【球员贡献】
{player_data.to_string()}
【
1. 高位逼抢成功率:{stats['percentage']}
2. 最高效逼抢区域:{zone_data['高位逼抢'].idxmax()}
3. 最佳逼抢球员:{player_data.index[0] if not player_data.empty else '暂无数据'}
========================================
"""
return report
# 使用示例
def main():
# 创建分析器
analyzer = HighPressAnalyzer()
# 生成模拟数据
print("正在生成模拟比赛数据...")
analyzer.generate_match_data(num_events=150)
# 统计高位逼抢球权恢复
stats = analyzer.count_high_press_recoveries()
print("\n=== 高位逼抢球权恢复统计 ===")
print(f"总球权恢复次数: {stats['total_recoveries']}")
print(f"高位逼抢恢复次数: {stats['high_press_recoveries']}")
print(f"高位逼抢占比: {stats['percentage']}")
# 区域分析
print("\n=== 按区域分析 ===")
zone_data = analyzer.analyze_by_zone()
print(zone_data)
# 球员分析
print("\n=== 按球员分析 ===")
player_data = analyzer.analyze_by_player()
print(player_data)
# 时间分析
print("\n=== 按时间段分析 ===")
time_data = analyzer.analyze_over_time()
print(time_data)
# 生成报告
reporter = MatchReporter(analyzer)
print("\n" + reporter.generate_report())
# 可视化
analyzer.visualize_results()
# 额外:保存详细数据到CSV
save_recovery_data(analyzer.recoveries, "high_press_recoveries.csv")
def save_recovery_data(recoveries: List[BallRecovery], filename: str):
"""保存恢复数据到CSV文件"""
data = []
for r in recoveries:
data.append({
'时间(分钟)': r.minute,
'球员': r.player,
'区域': r.zone,
'恢复方式': r.recovery_type,
'压力等级': r.pressure_level,
'后续发展': r.outcome,
'是否高位逼抢': '是' if r.is_high_press else '否'
})
df = pd.DataFrame(data)
df.to_csv(filename, index=False, encoding='utf-8-sig')
print(f"\n数据已保存到: {filename}")
if __name__ == "__main__":
main()
关键功能说明
数据生成
- 模拟生成比赛的球权恢复数据
- 包含位置、球员、区域、方式等信息
核心统计功能
count_high_press_recoveries(): 统计高位逼抢总次数analyze_by_zone(): 按区域分析analyze_by_player(): 按球员分析analyze_over_time(): 按时间段分析
可视化
- 饼图显示总体分布
- 柱状图对比不同区域
- 排名图显示最佳球员
- 趋势图分析时间分布
报告生成
- 自动生成详细分析报告
- 保存数据到CSV文件
运行这个代码后,你会得到详细的统计结果和可视化图表,清楚地看到高位逼抢夺回球权的次数和分布情况。