低位防守解围次数统计脚本
我来帮你写一个统计低位防守解围次数的脚本,由于没有具体的数据格式,我先给出一个通用框架,你需要根据实际数据调整。

基础版本(Python + pandas)
import pandas as pd
def count_low_block_clearances(events_df):
"""
统计低位防守时的解围次数
参数:
events_df: 事件数据 DataFrame,需包含以下列:
- event_type: 事件类型(如 'Clearance')
- x: 事件发生位置的 x 坐标(0-100,假设进攻方向从左到右)
- y: 事件发生位置的 y 坐标
- team: 球队
"""
# 定义低位防守区域:本方后场 1/3(x < 33.3)
LOW_BLOCK_X_THRESHOLD = 33.3
# 筛选解围事件
clearances = events_df[events_df['event_type'] == 'Clearance'].copy()
# 筛选低位区域的解围
low_block_clearances = clearances[clearances['x'] < LOW_BLOCK_X_THRESHOLD]
# 按球队统计
result = low_block_clearances.groupby('team').size().reset_index(name='low_block_clearance_count')
return result
# 使用示例
if __name__ == "__main__":
# 加载你的数据(根据实际情况修改)
df = pd.read_csv("events.csv")
result = count_low_block_clearances(df)
print(result)
进阶版本(含更多防守指标)
import pandas as pd
class DefensiveStatsAnalyzer:
def __init__(self, events_df, pitch_length=105, pitch_width=68):
self.df = events_df
self.pitch_length = pitch_length
self.pitch_width = pitch_width
def _normalize_coords(self):
"""将坐标标准化到 0-100 范围"""
df = self.df.copy()
# 若 x 已经是 0-100 则跳过;若是米制则转换
if df['x'].max() > 100:
df['x_norm'] = df['x'] / self.pitch_length * 100
else:
df['x_norm'] = df['x']
return df
def count_low_block_clearances(self, x_threshold=33.3, team=None, opponent=None):
"""
统计低位防守解围次数
x_threshold: 低位区域阈值(默认本方后场1/3)
team: 指定球队(可选)
opponent: 指定对手(可选)
"""
df = self._normalize_coords()
mask = (
(df['event_type'].str.lower() == 'clearance') &
(df['x_norm'] < x_threshold)
)
if team:
mask &= (df['team'] == team)
if opponent:
mask &= (df['opponent'] == opponent)
filtered = df[mask]
return filtered.groupby('team').size().sort_values(ascending=False)
def detailed_report(self):
"""生成完整防守报告"""
report = {
'低位解围总数': len(self.df[
(self.df['event_type'].str.lower() == 'clearance') &
(self._normalize_coords()['x_norm'] < 33.3)
]),
'按球队统计': self.count_low_block_clearances().to_dict()
}
return report
# 使用示例
if __name__ == "__main__":
df = pd.read_csv("events.csv")
analyzer = DefensiveStatsAnalyzer(df)
print(analyzer.detailed_report())
需要你确认的关键点
为了让脚本精确匹配你的数据,请告诉我:
- 数据来源:StatsBomb / Opta / Wyscout / 自建数据?
- 数据格式:CSV、JSON、还是数据库?字段名是什么?
- "低位防守"的定义:
- 固定阈值(如 x < 33)?
- 动态判断(如球队防线平均位置靠后)?
- 是否考虑比赛情境(领先/落后)?
- 解围事件类型:
Clearance/Clearance Successful/ 其他? - 坐标体系:0-100 归一化?米制 105×68?还是球队视角需要翻转?
常见数据源字段参考
| 数据源 | 解围字段 | 坐标字段 |
|---|---|---|
| StatsBomb | pass.type == 'Clearance' 或 clearance 事件 |
location: [x, y] (0-120, 0-80) |
| Opta | type_id == 8 (Clearance) |
x, y (0-100) |
| Wyscout | eventName == 'Clearance' |
positions[0].x/y (0-100) |
告诉我你的具体数据源和格式,我可以给你一个开箱即用的精确版本。