如何分析双方射门转化率差异
在Python中分析足球比赛双方射门转化率(进球数 / 射门数)差异,通常需要以下几个步骤,下面给你一个完整的思路和示例代码。

核心指标
# 射门转化率 = 进球数 / 射门数 conversion_rate = goals / shots
对比双方时通常关注:
- 绝对差异:
主队转化率 - 客队转化率 - 相对差异:
(主队转化率 - 客队转化率) / 客队转化率 - 显著性检验:这个差异是真实实力体现,还是运气波动?
基础对比示例
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 示例数据
data = {
'team': ['主队', '客队'],
'shots': [15, 8],
'shots_on_target': [6, 3],
'goals': [2, 1]
}
df = pd.DataFrame(data)
# 计算转化率
df['conversion_rate'] = df['goals'] / df['shots']
df['on_target_rate'] = df['shots_on_target'] / df['shots']
df['conversion_per_ontarget'] = df['goals'] / df['shots_on_target']
print(df)
输出:
team shots shots_on_target goals conversion_rate on_target_rate conversion_per_ontarget
0 主队 15 6 2 0.133333 0.400000 0.333333
1 客队 8 3 1 0.125000 0.375000 0.333333
可视化对比
fig, axes = plt.subplots(1, 3, figsize=(14, 4))
metrics = ['conversion_rate', 'on_target_rate', 'conversion_per_ontarget']s = ['射门转化率', '射正率', '射正转化率']
for ax, m, t in zip(axes, metrics, titles):
ax.bar(df['team'], df[m], color=['#e74c3c', '#3498db'])
ax.set_title(t)
ax.set_ylim(0, max(df[m]) * 1.3)
for i, v in enumerate(df[m]):
ax.text(i, v + 0.005, f'{v:.1%}', ha='center')
plt.tight_layout()
plt.show()
判断差异是否"显著"
小样本下转化率差异很容易受运气影响,推荐用卡方检验或泊松检验:
from scipy.stats import chi2_contingency
# 列联表:[[主队进球, 主队未进球], [客队进球, 客队未进球]]
table = [
[df.loc[0, 'goals'], df.loc[0, 'shots'] - df.loc[0, 'goals']],
[df.loc[1, 'goals'], df.loc[1, 'shots'] - df.loc[1, 'goals']]
]
chi2, p, dof, expected = chi2_contingency(table)
print(f"卡方值 = {chi2:.3f}, p值 = {p:.3f}")
if p < 0.05:
print("双方转化率差异显著")
else:
print("差异不显著,可能只是运气")
对于单场比赛,样本量通常太小,p值几乎都会 > 0.05,这是正常的。
看转化率差异的实战建议
| 观察角度 | 说明 |
|---|---|
| 绝对差 | 直接相减,直观但对样本量敏感 |
| 相对差 | 除以客队,反映倍数关系 |
| 与联赛均值比 | 判断是高于还是低于正常水平 |
| 结合射正率 | 转化率低可能因为射门质量差(射正率低) |
| 长期 vs 单场 | 长期才有统计意义,单场看趋势 |
进阶:用 xG 校正
更专业的做法是使用 xG(预期进球) 代替实际转化率:
df['xg_conversion'] = df['goals'] / df['xg'] # 实际进球 / 预期进球 # >1 表示把握机会能力强,<1 表示浪费机会
总结一句话:看转化率差异 = 先算 goals/shots 对比数值,再用卡方/泊松检验判断差异是否显著,最后结合射正率、xG 等指标理解差异来源,避免被小样本的"运气"误导。
需要我针对你具体的比赛数据写一段可直接运行的代码吗?