用Python分析球队打法风格案例
下面给你一个完整可运行的Python案例,通过比赛数据(进球、控球、射门、传球、抢断等)判断一支球队擅长什么打法,用的是聚类 + 雷达图的思路,非常适合入门实战。

案例目标
输入一支球队的多项技术统计,输出它属于哪种打法风格:
| 打法风格 | 特征 |
|---|---|
| 传控流 | 高控球率、高传球成功率、短传多 |
| 防守反击 | 低控球、抢断多、反击进球多 |
| 高位逼抢 | 前场抢断多、对手失误多、跑动距离大 |
| 长传冲吊 | 长传比例高、头球争顶多、传中多 |
| 边路进攻 | 传中次数多、边路突破多 |
数据准备
先用一份模拟的球队数据(真实项目可替换为 Opta / FBref / 懂球帝数据):
import pandas as pd
import numpy as np
# 每行代表一支球队的一个赛季数据
data = {
'球队': ['曼城', '利物浦', '皇马', '马竞', '拜仁', '切尔西', '阿森纳', '多特'],
'控球率': [65, 58, 55, 42, 62, 54, 60, 50],
'传球成功率': [90, 84, 86, 78, 88, 83, 87, 80],
'长传比例': [8, 12, 11, 22, 10, 15, 9, 18],
'场均射门': [17, 18, 15, 11, 16, 13, 15, 14],
'场均抢断': [14, 16, 13, 20, 12, 15, 13, 14],
'前场抢断': [8, 10, 6, 5, 7, 6, 8, 5],
'场均传中': [15, 20, 18, 10, 22, 19, 14, 21],
'反击进球占比': [5, 12, 15, 25, 8, 13, 6, 10],
'头球争顶成功率': [50, 55, 52, 60, 58, 54, 48, 62],
}
df = pd.DataFrame(data)
print(df)
关键步骤:标准化 + KMeans聚类
不同指标量纲不同,先标准化,再用聚类自动分出"打法类型":
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
features = ['控球率', '传球成功率', '长传比例', '场均射门',
'场均抢断', '前场抢断', '场均传中', '反击进球占比', '头球争顶成功率']
X = df[features]
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 假设分3类(可根据肘部法调整)
kmeans = KMeans(n_clusters=3, random_state=42, n_init=10)
df['风格聚类'] = kmeans.fit_predict(X_scaled)
print(df[['球队', '风格聚类']])
给每个聚类"翻译"成打法风格
聚类结果只是 0/1/2,需要人肉/规则映射,这里用聚类中心特征自动解读:
# 查看每个聚类的平均特征(还原到原始量纲感官更好)
centers = pd.DataFrame(
scaler.inverse_transform(kmeans.cluster_centers_),
columns=features
).round(1)
print(centers)
假设输出类似:
| 聚类 | 控球 | 传球成功 | 长传 | 抢断 | 前场抢断 | 传中 | 反击占比 |
|---|---|---|---|---|---|---|---|
| 0 | 62 | 88 | 9 | 13 | 7 | 17 | 6 |
| 1 | 43 | 78 | 22 | 20 | 5 | 10 | 25 |
| 2 | 55 | 84 | 12 | 15 | 9 | 21 | 12 |
自动命名逻辑:
def name_style(row):
if row['控球率'] > 58 and row['传球成功率'] > 85:
return '传控流'
elif row['反击进球占比'] > 20 and row['长传比例'] > 18:
return '防守反击/长传冲吊'
elif row['前场抢断'] > 8 and row['场均传中'] > 18:
return '高位逼抢+边路'
else:
return '均衡型'
# 用聚类中心匹配风格
style_map = {i: name_style(centers.iloc[i]) for i in range(len(centers))}
df['打法风格'] = df['风格聚类'].map(style_map)
print(df[['球队', '打法风格']])
输出示例:
球队 打法风格
0 曼城 传控流
1 利物浦 高位逼抢+边路
2 皇马 均衡型
3 马竞 防守反击/长传冲吊
...
可视化:雷达图对比
选两支风格差异大的队(如曼城 vs 马竞)画雷达图:
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 中文显示
plt.rcParams['axes.unicode_minus'] = False
def radar(team_row, color, label):
values = team_row[features].values.astype(float)
# 归一化到0-1便于对比
values_norm = (values - X[features].min().values) / (X[features].max().values - X[features].min().values)
angles = np.linspace(0, 2*np.pi, len(features), endpoint=False).tolist()
values_norm = np.concatenate([values_norm, [values_norm[0]]])
angles += angles[:1]
ax.plot(angles, values_norm, color=color, label=label)
ax.fill(angles, values_norm, color=color, alpha=0.15)
fig, ax = plt.subplots(figsize=(7,7), subplot_kw=dict(polar=True))
radar(df[df['球队']=='曼城'].iloc[0], 'skyblue', '曼城(传控)')
radar(df[df['球队']=='马竞'].iloc[0], 'red', '马竞(防反)')
ax.set_xticks(np.linspace(0, 2*np.pi, len(features), endpoint=False))
ax.set_xticklabels(features)
ax.legend(loc='upper right', bbox_to_anchor=(1.3, 1.1))'球队打法风格雷达图')
plt.show()
雷达图上能一眼看出:曼城控球/传球凸出,马竞抢断/长传/反击凸出。
进阶思路(可交付真实项目)
- 数据源:用
requests抓取 FBref / Sofascore 的赛季统计,替换模拟数据。 - 更多特征:PPDA(防守强度)、xG、边路进攻占比、场均跑动距离、进攻三区传球数。
- 动态分析:按赛季/对手拆分,看同一球队风格演变(如瓜迪奥拉曼城从边后卫内收到伪9号的演化)。
- 对阵克制:把两支球队的风格向量做相似度/互补分析,预测"谁克制谁"。
- 可视化升级:用
mplsoccer画球场热图、传球网络图,更贴近专业分析。
如果你有真实数据来源(比如某联赛一个赛季的球队统计),告诉我字段名,我可以帮你把上面的代码改成直接对接你数据的版本。