本文目录导读:

我来帮你创建一个统计高位逼抢中夺回球权次数的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文件
运行这个代码后,你会得到详细的统计结果和可视化图表,清楚地看到高位逼抢夺回球权的次数和分布情况。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播