本文目录导读:

在足球比赛中,“撞墙式配合”(也叫“二过一”)在足球统计里通常被归类为“最后一传”(Key Pass)或“直接传球”(One-touch Pass)的变体,但它没有标准化的官方统计字段,要统计这个,通常需要自定义脚本来处理事件数据(Event Data)。
这里为你提供三种不同难度的实用脚本方案,从纯Python逻辑到使用数据分析库:
纯Python逻辑(最易理解,适合处理JSON数据)
如果你有比赛的事件数据(通常包含x, y坐标,timestamp时间戳,player和type字段),这个脚本可以帮你识别出“短距离快速回传后直塞”的模式。
import json
from math import sqrt
# 假设数据格式为 [{'player': 10, 'type': 'pass', 'x': 50, 'y': 30, 'end_x': 40, 'end_y': 30, 'time': 10.2}, ...]
# 请根据你的实际数据修改这些字段名
def load_data(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
return json.load(f)
def is_pass(event):
"""判断是不是传球"""
return event.get('type') == 'pass'
def calculate_distance(x1, y1, x2, y2):
"""计算欧氏距离"""
return sqrt((x2 - x1)**2 + (y2 - y1)**2)
def detect_wall_pass(events, max_time_gap=2.0, max_pass_distance=25.0):
"""
撞墙式配合检测逻辑(简化版):
1. A球员传给B球员(第一次传递)
2. B球员不停球(或极短时间内)直接回传给A球员所在的附近区域(第二次传递,第一脚触球就传)
3. A球员向前推进(第三次传递发生在更靠近球门的位置)
"""
wall_pass_count = 0
for i in range(len(events) - 2):
# 获取连续的三个事件
pass1 = events[i]
pass2 = events[i + 1]
pass3 = events[i + 2]
# 条件1:都是传球
if not (is_pass(pass1) and is_pass(pass2) and is_pass(pass3)):
continue
# 条件2:时间上很接近(一次触球)
if (pass2.get('time', 0) - pass1.get('time', 0)) > max_time_gap:
continue
# 条件3:第一次传递的距离较短(短传)
dist1 = calculate_distance(pass1.get('x'), pass1.get('y'),
pass1.get('end_x'), pass1.get('end_y'))
if dist1 > max_pass_distance:
continue
# 条件4:第二次传球是“回敲”(球回到了第一个传球者的附近)
# 找第一个传球者的最终位置(假设pass1的end就是pass2的start,这里简化)
# 实际上我们需要看pass2的x,y(起脚位置)是否接近pass1的x,y(发起位置)
start_dist = calculate_distance(pass2.get('x'), pass2.get('y'),
pass1.get('x'), pass1.get('y'))
if start_dist > 15.0: # 如果B球员接球位置离A球员太远,不算
continue
# 条件5:第三次传球必须向前推进(传向对方半场,或接近球门)
if pass3.get('end_x') <= pass1.get('end_x'):
continue # 没有向前推进
# 如果都满足,计数
wall_pass_count += 1
return wall_pass_count
# 主程序
if __name__ == "__main__":
# 伪造一点示例数据
fake_events = [
{'player': 7, 'type': 'pass', 'x': 50, 'y': 50, 'end_x': 40, 'end_y': 50, 'time': 10.0}, # A给B
{'player': 9, 'type': 'pass', 'x': 40, 'y': 50, 'end_x': 50, 'end_y': 48, 'time': 10.5}, # B回给A
{'player': 7, 'type': 'pass', 'x': 50, 'y': 48, 'end_x': 60, 'end_y': 45, 'time': 11.0} # A向前传
]
count = detect_wall_pass(fake_events)
print(f"检测到撞墙式配合次数: {count}")
使用 Pandas(进阶版,处理大型CSV文件)
如果数据量很大,用Pandas进行矢量化操作速度更快。
import pandas as pd
import numpy as np
# 假设CSV文件列名为: player_id, event_type, x, y, end_x, end_y, match_time
df = pd.read_csv('event_data.csv')
# 只保留传球事件
passes = df[df['event_type'] == 'pass'].reset_index(drop=True)
# 计算传球距离
passes['pass_dist'] = np.sqrt((passes['end_x'] - passes['x'])**2 + (passes['end_y'] - passes['y'])**2)
# 核心逻辑:利用DataFrame的shift()函数错位比较
# 找出所有连续三行传球,且间隔时间短
passes['time_gap_next'] = passes['match_time'].shift(-1) - passes['match_time']
passes['is_short_pass'] = passes['pass_dist'] < 25 # 短传
# 找到“回传”(第二次传球结束点接近第一次传球起始点)
passes['return_pass'] = ((passes['end_x'].shift(1) - passes['x']) ** 2 +
(passes['end_y'].shift(1) - passes['y']) ** 2) ** 0.5 < 15
# 找到向前推进(第三次传球终结位置比第一次更靠前)
passes['forward_progress'] = passes['end_x'].shift(-2) > passes['end_x'] + 5
# 统计满足所有条件的组合
result = passes[
(passes['is_short_pass']) & # 第一脚是短传
(passes['time_gap_next'] < 2) & # 时间连续
(passes['return_pass'].shift(1)) & # 第二脚是回传
(passes['forward_progress'].shift(-2)) # 第三脚向前
]
print(f"总撞墙次数: {len(result)}")
针对“视频标签”的简易脚本(适合手动打点)
如果你没有自动化数据,而是通过观看比赛录像手动标注了“传球发起点”和“传球结束点”(比如你在Excel里记录了球员A触球位置和球员B触球位置),这个脚本可以帮你计算:
# 场景:你记录了每一次触球的坐标(X,Y),以及是哪名球员
# 撞墙式配合的规则:
# 1. 3次快速触球,涉及3个球员(通常是A-B-A)
# 2. 第一次传球和第二次传球都发生在极短时间内
touch_sequence = [
('A', 50, 50, 10.0), # (球员, x, y, 时间)
('B', 45, 48, 10.2),
('A', 50, 49, 10.4),
('C', 60, 40, 12.0), # 这个间隔时间变长,不算
# ... 继续记录
]
def count_wall_passes(seq, time_threshold=1.0):
count = 0
i = 0
while i < len(seq) - 2:
p1, p2, p3 = seq[i], seq[i+1], seq[i+2]
# 判断是否是 A-B-A 模式(球员1 == 球员3 且 球员2 != 球员1)
if p1[0] == p3[0] and p1[0] != p2[0]:
# 判断时间是否极短
if (p3[3] - p1[3]) < time_threshold:
# 检查距离(球传出去又传回来)
dist1 = ((p2[1] - p1[1])**2 + (p2[2] - p1[2])**2)**0.5
dist2 = ((p3[1] - p2[1])**2 + (p3[2] - p2[2])**2)**0.5
# 两次传球距离都相对短(< 30米)
if dist1 < 30 and dist2 < 30:
count += 1
print(f"识别到撞墙: {p1[0]} -> {p2[0]} -> {p3[0]} (时间间隔: {p3[3]-p1[3]:.1f}s)")
i += 2 # 跳过这两次传球,避免重复计数
continue
i += 1
return count
# 使用示例
result = count_wall_passes(touch_sequence)
print(f"撞墙次数: {result}")
重要提示(撞墙”的定义)
在实际的足球数据分析中(如StatsBomb),撞墙式配合并没有一个固定的官方代码,通常分析师会使用“透视传球”(Throughball)或“连续传球次数”(Sequential Passes)来做替代统计。
如果你需要更精准的定义,可以告诉我:
- 你的数据源格式(是JSON、CSV还是SofaScore/WhoScored的API?)
- 你对“撞墙”的界定(必须是一脚出球吗?可以隔几秒吗?必须推进到对方半场吗?)
我可以为你调整脚本参数。
版权声明: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直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播