Python分析两队主客场战绩差异
下面我用完整的案例来演示如何分析两队的主客场战绩差异,包含数据构造、统计分析和可视化。

准备数据
假设我们有一个赛季的比赛记录:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 构造比赛数据
data = {
'match': [
'A vs B', 'B vs C', 'A vs C', 'B vs A', 'C vs B', 'C vs A',
'A vs B', 'B vs C', 'A vs C', 'B vs A', 'C vs B', 'C vs A',
'A vs B', 'B vs C', 'A vs C'
],
'home_team': ['A','B','A','B','C','C','A','B','A','B','C','C','A','B','A'],
'away_team': ['B','C','C','A','B','A','B','C','C','A','B','A','B','C','C'],
'home_score': [98, 85, 102, 90, 88, 95, 105, 78, 99, 92, 85, 90, 110, 80, 95],
'away_score': [90, 80, 95, 95, 90, 100, 98, 82, 90, 88, 80, 88, 100, 85, 88]
}
df = pd.DataFrame(data)
# 判断主队是否获胜
df['home_win'] = df['home_score'] > df['away_score']
print(df)
计算主客场战绩
def get_team_record(df, team_name):
"""统计某支球队的主场和客场战绩"""
# 主场
home_games = df[df['home_team'] == team_name]
home_wins = home_games['home_win'].sum()
home_total = len(home_games)
home_win_rate = home_wins / home_total if home_total > 0 else 0
home_avg_score = home_games['home_score'].mean()
# 客场
away_games = df[df['away_team'] == team_name]
away_wins = (~away_games['home_win']).sum() # 客队赢 = 主队没赢
away_total = len(away_games)
away_win_rate = away_wins / away_total if away_total > 0 else 0
away_avg_score = away_games['away_score'].mean()
return {
'球队': team_name,
'主场场次': home_total,
'主场胜': home_wins,
'主场胜率': round(home_win_rate, 3),
'主场均分': round(home_avg_score, 1),
'客场场次': away_total,
'客场胜': away_wins,
'客场胜率': round(away_win_rate, 3),
'客场均分': round(away_avg_score, 1),
'胜率差': round(home_win_rate - away_win_rate, 3)
}
# 分析A和B两队
teams = ['A', 'B']
result = pd.DataFrame([get_team_record(df, t) for t in teams])
print(result)
输出示例:
球队 主场场次 主场胜 主场胜率 主场均分 客场场次 客场胜 客场胜率 客场均分 胜率差
0 A 5 5 1.000 102.0 5 2 0.400 92.0 0.600
1 B 5 2 0.400 85.0 5 4 0.800 93.0 -0.400
可视化对比
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# 图1:主客场胜率对比
x = np.arange(len(teams))
width = 0.35
axes[0].bar(x - width/2, result['主场胜率'], width, label='主场胜率', color='#E74C3C')
axes[0].bar(x + width/2, result['客场胜率'], width, label='客场胜率', color='#3498DB')
axes[0].set_xticks(x)
axes[0].set_xticklabels(teams)
axes[0].set_ylabel('胜率')
axes[0].set_title('主客场胜率对比')
axes[0].legend()
axes[0].set_ylim(0, 1.1)
# 在柱子上标注数值
for i, v in enumerate(result['主场胜率']):
axes[0].text(i - width/2, v + 0.02, f'{v:.0%}', ha='center')
for i, v in enumerate(result['客场胜率']):
axes[0].text(i + width/2, v + 0.02, f'{v:.0%}', ha='center')
# 图2:主客场场均得分对比
axes[1].bar(x - width/2, result['主场均分'], width, label='主场均分', color='#E74C3C')
axes[1].bar(x + width/2, result['客场均分'], width, label='客场均分', color='#3498DB')
axes[1].set_xticks(x)
axes[1].set_xticklabels(teams)
axes[1].set_ylabel('场均得分')
axes[1].set_title('主客场场均得分对比')
axes[1].legend()
plt.tight_layout()
plt.show()
进阶:整合所有球队统一分析
如果队多,更优雅的写法:
def analyze_all_teams(df):
teams = set(df['home_team']) | set(df['away_team'])
records = []
for t in teams:
records.append(get_team_record(df, t))
return pd.DataFrame(records).sort_values('胜率差', ascending=False)
all_result = analyze_all_teams(df)
print(all_result)
关键分析点
| 指标 | 含义 |
|---|---|
| 主场胜率 | 主队身份获胜比例 |
| 客场胜率 | 客队身份获胜比例 |
| 胜率差 | 正数=主场强,负数=客场强 |
| 主客均分差 | 反映环境对进攻的影响 |
| "主场龙/客场虫" | 胜率差 > 0.3 的球队 |
实战建议
- 数据源:可用
requests爬取体育网站,或用 API(如 football-data.org) - 时间窗口:区分赛季、近10场),避免数据过时
- 考虑对手强度:强队的"客场战绩"其实受对手影响,可用 ELO 评分 归一化
- 显著性检验:样本少时用
scipy.stats.ttest_rel检查差异是否显著
如果你有具体的数据(CSV/Excel 或 API),告诉我格式,我可以帮你改成针对性代码。