本文目录导读:

我理解你说的“二点球”,大概率是指足球里的 第二落点/二次球(second ball) 争夺。
如果你指的是篮球的二次进攻篮板,那算法会不一样——下面我先按足球的“二点球”来讲。
一个实用的“二点球争夺谁占优”脚本,核心不是只看谁顶到了第一下,而是看:
- 第一点球之后,球权归谁
- 谁赢下了第二落点
- 争夺发生在哪些区域
- 哪些球员/球队更容易抢到二点球
脚本思路
输入数据
通常需要这些事件数据:
- 传球
- 争顶
- 抢断
- 解围
- 拦截
- 球权转换
- 地点坐标 x, y
- 时间戳
- 球队/球员
判定逻辑
可以这样定义“二点球”:
在一次空中对抗、长传、解围、门将开球或争顶之后,下一次由哪支球队成功控制球权,就算哪支球队赢下二点球。
更严格一点:
- 第一点球:第一次争顶/解围/门将击球
- 第二点球:随后 5~10 秒内,第一次稳定控球
- 如果球出界、犯规、死球,则不算
Python 实用脚本示例
下面这个脚本是一个简化版分析框架,可以统计:
- 两队二点球争夺次数
- 各队赢下次数
- 二点球胜率
- 哪些区域二点球最多
- 哪些球员最常赢下二点球
import pandas as pd
# 示例数据:你可以替换成 StatsBomb / Opta / Wyscout 导出数据
# event_type: pass, aerial, clearance, interception, tackle, recovery, shot, foul, out
# outcome: success / fail
# team: A / B
# player: 球员名
# x, y: 0-100 坐标系
# timestamp: 秒
data = [
# 第一点球事件
{"event_id": 1, "timestamp": 10, "event_type": "aerial", "outcome": "fail", "team": "A", "player": "A1", "x": 50, "y": 50},
{"event_id": 2, "timestamp": 12, "event_type": "clearance", "outcome": "success", "team": "B", "player": "B1", "x": 48, "y": 52},
{"event_id": 3, "timestamp": 14, "event_type": "recovery", "outcome": "success", "team": "B", "player": "B2", "x": 45, "y": 55},
# 另一回合
{"event_id": 4, "timestamp": 30, "event_type": "aerial", "outcome": "success", "team": "A", "player": "A2", "x": 70, "y": 40},
{"event_id": 5, "timestamp": 32, "event_type": "pass", "outcome": "fail", "team": "A", "player": "A2", "x": 72, "y": 42},
{"event_id": 6, "timestamp": 34, "event_type": "recovery", "outcome": "success", "team": "B", "player": "B3", "x": 75, "y": 38},
# 第三回合
{"event_id": 7, "timestamp": 60, "event_type": "clearance", "outcome": "success", "team": "A", "player": "A3", "x": 20, "y": 60},
{"event_id": 8, "timestamp": 62, "event_type": "recovery", "outcome": "success", "team": "A", "player": "A4", "x": 22, "y": 58},
]
df = pd.DataFrame(data)
# 定义哪些事件算“第一点球”触发事件
first_ball_events = ["aerial", "clearance", "interception", "tackle"]
# 定义哪些事件算“稳定控球/二点球赢下”
second_ball_events = ["recovery", "pass", "interception", "tackle"]
# 时间窗口:第一点球后多少秒内算二点球争夺
TIME_WINDOW = 8
second_ball_records = []
for i, row in df.iterrows():
if row["event_type"] in first_ball_events:
first_time = row["timestamp"]
first_team = row["team"]
first_x, first_y = row["x"], row["y"]
# 找时间窗口内的后续事件
later = df[
(df["timestamp"] > first_time) &
(df["timestamp"] <= first_time + TIME_WINDOW)
]
# 找第一次稳定控球
for _, nxt in later.iterrows():
if nxt["event_type"] in second_ball_events and nxt["outcome"] == "success":
second_ball_records.append({
"first_event_id": row["event_id"],
"first_team": first_team,
"first_event": row["event_type"],
"first_x": first_x,
"first_y": first_y,
"second_team": nxt["team"],
"second_player": nxt["player"],
"second_event": nxt["event_type"],
"second_x": nxt["x"],
"second_y": nxt["y"],
"time_gap": nxt["timestamp"] - first_time,
"second_ball_winner": nxt["team"]
})
break
second_df = pd.DataFrame(second_ball_records)
print("二点球争夺明细:")
print(second_df)
print("\n各队赢下二点球次数:")
print(second_df["second_ball_winner"].value_counts())
print("\n各队二点球胜率:")
win_counts = second_df["second_ball_winner"].value_counts()
total = len(second_df)
for team in ["A", "B"]:
wins = win_counts.get(team, 0)
rate = wins / total if total > 0 else 0
print(f"{team}: {wins}/{total} = {rate:.1%}")
print("\n赢下二点球最多的球员:")
print(second_df["second_player"].value_counts().head(10))
print("\n二点球发生区域分布:")
second_df["zone"] = pd.cut(
second_df["second_x"],
bins=[0, 33, 66, 100],
labels=["后场", "中场", "前场"]
)
print(second_df["zone"].value_counts())
这个脚本能回答什么?
运行后会输出:
- 谁赢下了更多二点球
- 哪队二点球胜率高
- 哪些球员最会抢二点球
- 二点球主要发生在后场、中场还是前场
- 第一点球是谁顶到/解围的,但第二点球被谁拿走了
例如输出可能像:
各队赢下二点球次数: B 2 A 1 各队二点球胜率: A: 1/3 = 33.3% B: 2/3 = 66.7% 赢下二点球最多的球员: B2 1 B3 1 A4 1
这就说明:B 队虽然不一定赢下第一点,但二点球争夺占优。
如果你要更专业的版本
真实比赛分析里,建议加这些规则:
-
排除死球阶段
犯规、越位、界外球、门球、角球后重新开始不算
-
区分“控球”和“碰到球”
- 解围踢到对方脚下,不算真正赢下二点球
- 需要下一次成功传球/带球/控球才算
-
加入对抗强度
- 周围 5 米内有多少人
- 是否发生第二次争顶
-
加入 xT / 危险程度
二点球赢下后是否形成射门、传中、反击
-
按区域统计
- 进攻三区二点球胜率更重要
- 防守三区二点球胜率关系防守稳定性
如果你说的是篮球的“二点球”
那通常指:
- 二次进攻
- 前场篮板后的补篮
- 二次进攻得分
篮球脚本逻辑会变成:
- 投篮不中
- 谁抢到前场篮板
- 谁补篮得分
- 二次进攻得分/回合
如果你告诉我你手头的数据格式,
- 是 StatsBomb 还是 Opta?
- 是足球还是篮球?
- 有没有 x/y 坐标?
- 是 CSV 还是 JSON?
我可以直接给你改成能跑你数据的版本。