本文目录导读:

统计头球争顶成功率(Aerial Duels Won Rate)是足球数据分析中非常实用的一个指标,下面我提供一个基于Python的实用脚本,它能够处理比赛事件数据并输出头球争顶的成功率。
这个脚本会覆盖数据清洗、特征计算和结果输出三个方面,你可以直接复制或根据你的数据格式进行调整。
前提与数据结构
在大多数体育数据供应商(如Opta、StatsBomb)的数据中,头球争顶通常分为两类事件:
- 争顶成功:球员在空中对抗中赢得球权。
- 争顶失败:球员在空中对抗中失去球权(或未触到球)。
假设你的数据格式为(列名):
player:球员姓名event_type:事件类型("Aerial"或"Duel")duel_type:对抗类型("Aerial")outcome:结果("Won"或"Lost")minute:比赛时间
Python 脚本
import pandas as pd
import numpy as np
def calculate_aerial_duel_success_rate(df):
"""
计算头球争顶成功率(针对球员和球队)。
参数:
df (pd.DataFrame): 包含头球争顶事件的数据框。
返回:
pd.DataFrame: 包含头部争顶成功率的汇总数据。
"""
# 1. 数据清洗与筛选
# 只保留头球争顶事件(这里假设 duel_type == 'Aerial',或 event_type == 'Aerial')
aerial_df = df[
(df['event_type'] == 'Aerial') |
((df['duel_type'] == 'Aerial') & (df['event_type'] == 'Duel'))
].copy()
# 如果没有任何头球事件,返回空
if aerial_df.empty:
print("警告:数据中未找到头球争顶事件。")
return pd.DataFrame()
# 标准化结果列(处理大小写和不同表达方式)
aerial_df['outcome_normalized'] = aerial_df['outcome'].str.strip().str.lower()
aerial_df['is_won'] = np.where(aerial_df['outcome_normalized'].isin(['won', 'success', 'win', '1', 'true']), 1, 0)
# 2. 按球员统计
player_stats = aerial_df.groupby('player').agg(
总争顶次数=('is_won', 'count'),
成功次数=('is_won', 'sum')
).reset_index()
player_stats['成功率(%)'] = (player_stats['成功次数'] / player_stats['总争顶次数'] * 100).round(2)
player_stats = player_stats.sort_values('成功率(%)', ascending=False)
# 3. 按球队统计(如果数据中有球队列)
if 'team' in aerial_df.columns:
team_stats = aerial_df.groupby('team').agg(
总争顶次数=('is_won', 'count'),
成功次数=('is_won', 'sum')
).reset_index()
team_stats['成功率(%)'] = (team_stats['成功次数'] / team_stats['总争顶次数'] * 100).round(2)
team_stats = team_stats.sort_values('成功率(%)', ascending=False)
return player_stats, team_stats
else:
return player_stats
# --- 使用示例 ---
if __name__ == "__main__":
# 模拟一份虚拟数据(实际使用中请替换为你的数据源,如CSV或API)
data = {
'player': ['球员A', '球员B', '球员A', '球员C', '球员B', '球员A', '球员C', '球员A', '球员B', '球员B'],
'team': ['主队', '主队', '主队', '客队', '客队', '客队', '主队', '客队', '主队', '客队'],
'event_type': ['Aerial', 'Duel', 'Aerial', 'Aerial', 'Aerial', 'Duel', 'Aerial', 'Aerial', 'Aerial', 'Aerial'],
'duel_type': ['Aerial', 'Aerial', 'Aerial', 'Aerial', 'Aerial', 'Aerial', 'Aerial', 'Aerial', 'Aerial', 'Aerial'],
'outcome': ['Won', 'Lost', 'Lost', 'Won', 'Won', 'Won', 'Lost', 'Won', 'Lost', 'Won'], # Won=1, Lost=0
'minute': [10, 23, 45, 67, 70, 80, 85, 88, 90, 91]
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("\n")
# 计算成功率
result = calculate_aerial_duel_success_rate(df)
# 输出结果
if isinstance(result, tuple):
player_result, team_result = result
print("球员头球争顶成功率:")
print(player_result)
print("\n球队头球争顶成功率:")
print(team_result)
else:
print("头球争顶成功率:")
print(result)
脚本解释与扩展
- 筛选逻辑:脚本通过
event_type或duel_type来判断是否为头球争顶,如果数据源不同,只需修改这里的条件即可。 - 结果标准化:现实中不同数据源对“成功”的定义可能不同(如
Won,Succ),脚本已将常见的关键词统一映射为0和1。 - 统计维度:
- 球员维度:关注个人对抗能力。
- 球队维度(可选):关注整体高空对抗强度。
- 过滤条件扩展:你可以轻松增加额外参数,只统计禁区内的头球”或“只统计特定时间段”。
df = df[df['area'] == 'Defensive third']
- 百分比安全性:如果某球员争顶次数为0,
round()和sort_values会自动处理,但建议在输出前检查是否为空。
如果数据来自 CSV 文件
将脚本中的模拟数据部分替换为:
df = pd.read_csv('your_match_events.csv') # 你的CSV路径
如果数据是 JSON(如 StatsBomb):
df = pd.json_normalize(data, record_path='events') # 根据实际结构调整
进阶建议(可选增强)
如果你想统计“特定位置”(如中后卫)或“特定时刻”(如下半场最后15分钟),可以在函数中增加参数:
def calculate_aerial_duel_success_rate(df, position_filter=None, minute_filter=None):
# ... 在筛选后增加:
if position_filter:
df = df[df['position'] == position_filter]
if minute_filter:
df = df[df['minute'] >= minute_filter[0] & df['minute'] <= minute_filter[1]]
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播