本文目录导读:

统计头球争顶成功率(Aerial Duels Won Rate)在足球数据分析中非常实用,尤其是对于中后卫、前锋以及定位球战术的分析。
以下我为你提供三种不同场景的实用脚本方案,从基础到进阶,你可以根据你手头的数据格式(Excel/CSV)或编程环境(Python)来选择。
Python脚本(推荐,适合处理大量比赛数据)
如果你有包含比赛事件数据的 CSV 文件(例如从 Wyscout、StatsBomb 或自定义爬虫获取),这个脚本可以帮你快速聚合统计。
数据假设:你的数据是一行一个事件,包含球员ID、球员姓名、事件类型(Aerial)、结果(Won/Lost)。
import pandas as pd
def calculate_aerial_duel_success(data_path):
"""
统计头球争顶成功率(按球员分组)
参数:
data_path: CSV文件路径,需包含列:
player_name, player_id, duel_type, duel_result
"""
# 1. 读取数据
df = pd.read_csv(data_path)
# 2. 筛选出头球争顶事件(假设 duel_type 为 'air_duel' 或 'aerial')
# 如果你的数据里没有这一列,但只有 'height' 或 'body_part' 是 'Head',请修改这里
if 'duel_type' in df.columns:
aerial_df = df[df['duel_type'].str.contains('aerial|air', case=False, na=False)].copy()
elif 'body_part' in df.columns:
aerial_df = df[df['body_part'] == 'Head'].copy()
else:
print("错误:未找到区分头球争抢的列")
return
# 3. 标准化结果列:确保结果是 'Won' 或 1
# 假设 'Won' 或 True 代表成功
aerial_df['is_won'] = aerial_df['duel_result'].apply(
lambda x: 1 if x in ['Won', 'True', '1', 'Success'] else 0
)
# 4. 聚合统计
stats = aerial_df.groupby('player_name').agg(
total_duels=('is_won', 'count'), # 总争顶次数
won_duels=('is_won', 'sum'), # 成功次数
success_rate=('is_won', 'mean') # 成功率
).reset_index()
# 5. 格式化成功率(保留两位小数,转为百分比)
stats['success_rate'] = (stats['success_rate'] * 100).round(2).astype(str) + '%'
stats = stats.sort_values('total_duels', ascending=False)
print(stats.to_string(index=False))
# 可选:导出结果
stats.to_csv('aerial_duel_stats.csv', index=False)
return stats
# 使用示例
if __name__ == "__main__":
# 替换为你的文件路径
calculate_aerial_duel_success('your_match_events.csv')
Excel 公式(适合快速手工统计)
如果数据量不大,直接使用 Excel 的 COUNTIFS(多条件计数)和 SUMIFS(多条件求和)最方便。
假设数据结构:
- A列:球员名
- B列:是否为头球争顶(填写“是/否”或“Head”)
- C列:结果(填写“成功”或“失败”)
公式实现:
-
总争顶次数:
=COUNTIFS(A:A, "球员名字", B:B, "是")
-
成功次数:
=COUNTIFS(A:A, "球员名字", B:B, "是", C:C, "成功")
-
成功率:
=IFERROR(成功次数单元格/总争顶次数单元格, 0)
设置单元格格式为百分比即可。
进阶SQL脚本(适合数据库存储)
如果你在一家俱乐部或数据公司,数据存在数据库中,这是最标准的做法。
-- 假设表结构为:events (player_id, player_name, event_type, event_outcome)
-- 1. 筛选头球争顶(event_type = 'Duel' AND sub_type = 'Air')
-- 2. 统计
SELECT
player_name,
COUNT(*) AS total_duels,
SUM(CASE WHEN event_outcome = 'Won' THEN 1 ELSE 0 END) AS won_duels,
ROUND(
SUM(CASE WHEN event_outcome = 'Won' THEN 1.0 ELSE 0.0 END) / COUNT(*) * 100,
2
) AS success_rate
FROM events
WHERE event_type = 'Duel'
AND sub_type = 'Air' -- 或者标记为 Head
GROUP BY player_name, player_id
HAVING COUNT(*) >= 10 -- 过滤掉样本太少的情况,比如至少争顶10次以上
ORDER BY success_rate DESC;
统计时需要留意的细节
在统计时,有几组概念容易混淆,建议确认清楚再计算:
- 是“成功争顶”还是“对抗成功”:有时候后卫会把球顶出底线(解围),有时候前锋顶偏了,这里的“成功”通常指将球顶给本方队友或顶向目标球门/解围出危险区,而不是仅仅“碰到球”。
- 是否包含“地对空”:这里的“头球争顶”特指双方都跳起用头抢球的 50/50 球,如果是对方传中,后卫纯粹头球解围(无人干扰),通常不计入“争顶”统计,只算“头球解围”。
- 样本量过滤:对于只有几次争顶的球员,成功率会失真(比如争顶1次,成功1次,100%),脚本中建议设置
HAVING COUNT(*) >= 10或类似阈值,只统计主力球员。
如果你手头没有现成的数据文件,但有一堆比赛视频或文本描述,可能需要先进行数据清洗,欢迎告诉我你目前的数据是什么格式,我可以帮你调整脚本。