本文目录导读:

在Python中分析两队的主客场战绩差异,通常需要经历数据准备、数据清洗、统计分析和可视化四个步骤。
由于你没有提供具体的CSV或数据库格式,我假设你已经有一份包含比赛记录的数据表(例如CSV文件),包含以下关键字段:
Date(日期)Home_Team(主队名称)Away_Team(客队名称)Home_Score(主队得分)Away_Score(客队得分)
下面是完整的实战案例,使用 pandas 和 matplotlib / seaborn 来实现。
第一步:导入库并加载数据
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# 设置中文显示(避免乱码)
plt.rcParams['font.sans-serif'] = ['SimHei'] # 或者 'Arial Unicode MS' for Mac
plt.rcParams['axes.unicode_minus'] = False
# 假设你的数据在 'matches.csv' 中
df = pd.read_csv('matches.csv')
# 查看数据概览
print(df.head())
print(df.info())
第二步:数据处理(生成“胜平负”标记)
我们需要为每一场比赛确定主队和客队的胜负结果。
# 计算主队和客队的得分差 df['Home_Win'] = (df['Home_Score'] > df['Away_Score']).astype(int) df['Draw'] = (df['Home_Score'] == df['Away_Score']).astype(int) df['Away_Win'] = (df['Home_Score'] < df['Away_Score']).astype(int)
第三步:统计两队主客场战绩
我们想要看某两队之间的对话,或者全联盟球队各自的主客场胜率。
场景A:关注特定两队(湖人”和“勇士”)
def analyze_head_to_head(df, team_a, team_b):
# 筛选出这两队交手的比赛
mask = ((df['Home_Team'] == team_a) & (df['Away_Team'] == team_b)) | \
((df['Home_Team'] == team_b) & (df['Away_Team'] == team_a))
matches = df[mask].copy()
# 分别统计 A 队主场和客场战绩
a_home = matches[(matches['Home_Team'] == team_a)]
a_away = matches[(matches['Away_Team'] == team_a)]
# 计算A队主场胜率
a_home_wins = a_home['Home_Win'].sum()
a_home_losses = len(a_home) - a_home_wins - a_home['Draw'].sum()
# 计算A队客场胜率
a_away_wins = a_away['Away_Win'].sum()
a_away_losses = len(a_away) - a_away_wins - a_away['Draw'].sum()
result = {
'Team': team_a,
'Home_Played': len(a_home),
'Home_Wins': a_home_wins,
'Home_Losses': a_home_losses,
'Home_Win_Rate': round(a_home_wins / len(a_home) * 100, 1) if len(a_home) > 0 else 0,
'Away_Played': len(a_away),
'Away_Wins': a_away_wins,
'Away_Losses': a_away_losses,
'Away_Win_Rate': round(a_away_wins / len(a_away) * 100, 1) if len(a_away) > 0 else 0,
}
return result
# 使用示例
result = analyze_head_to_head(df, '湖人', '勇士')
print(result)
场景B:分析全联盟所有球队的主客场胜率对比
def analyze_all_teams(df):
all_teams = pd.unique(df[['Home_Team', 'Away_Team']].values.ravel())
records = []
for team in all_teams:
# 主场数据
home_games = df[df['Home_Team'] == team]
home_wins = home_games['Home_Win'].sum()
home_played = len(home_games)
home_rate = home_wins / home_played * 100 if home_played > 0 else 0
# 客场数据
away_games = df[df['Away_Team'] == team]
away_wins = away_games['Away_Win'].sum()
away_played = len(away_games)
away_rate = away_wins / away_played * 100 if away_played > 0 else 0
records.append({
'Team': team,
'Home_Played': home_played,
'Home_Win_Rate': round(home_rate, 1),
'Away_Played': away_played,
'Away_Win_Rate': round(away_rate, 1),
'Home_Away_Diff': round(home_rate - away_rate, 1) # 主客场差异值
})
return pd.DataFrame(records)
team_stats = analyze_all_teams(df)
print(team_stats.sort_values('Home_Away_Diff', ascending=False))
第四步:可视化对比
条形图对比(特定两队或全队)
# 假设用全联盟数据
team_stats_sorted = team_stats.sort_values('Home_Win_Rate', ascending=False).head(10)
fig, ax = plt.subplots(figsize=(12, 6))
x = np.arange(len(team_stats_sorted)) # 标签位置
width = 0.35 # 柱宽度
bars1 = ax.bar(x - width/2, team_stats_sorted['Home_Win_Rate'], width, label='主场胜率', color='#1f77b4')
bars2 = ax.bar(x + width/2, team_stats_sorted['Away_Win_Rate'], width, label='客场胜率', color='#ff7f0e')
ax.set_xlabel('球队')
ax.set_ylabel('胜率 (%)')
ax.set_title('球队主客场胜率对比 (Top 10)')
ax.set_xticks(x)
ax.set_xticklabels(team_stats_sorted['Team'], rotation=45, ha='right')
ax.legend()
ax.grid(axis='y', linestyle='--', alpha=0.7)
plt.tight_layout()
plt.show()
散点图(主场胜率 vs 客场胜率)
plt.figure(figsize=(8, 8))
sns.scatterplot(data=team_stats, x='Home_Win_Rate', y='Away_Win_Rate', s=100, color='purple')
# 添加对角线作为参考(如果主场=客场则在对角线上)
plt.plot([0, 100], [0, 100], 'k--', alpha=0.5, label='主客胜率相等')
# 为每个点标注球队名
for i, row in team_stats.iterrows():
plt.text(row['Home_Win_Rate']+0.5, row['Away_Win_Rate']+0.5, row['Team'], fontsize=8)
plt.xlabel('主场胜率 (%)')
plt.ylabel('客场胜率 (%)')'主场 vs 客场胜率散点图')
plt.grid(True, linestyle='--', alpha=0.5)
plt.legend()
plt.show()
第五步:进阶分析(关键洞察)
-
计算“主场优势”系数:
avg_home_rate = team_stats['Home_Win_Rate'].mean() avg_away_rate = team_stats['Away_Win_Rate'].mean() print(f"联盟平均主场胜率: {avg_home_rate:.1f}%") print(f"联盟平均客场胜率: {avg_away_rate:.1f}%") print(f"平均主场优势: {avg_home_rate - avg_away_rate:.1f} 个百分点") -
找出“客场虫”和“客场龙”:
# 主场强但客场弱的队伍(差距最大) print("\n主场优势最大的队伍:") print(team_stats.nlargest(5, 'Home_Away_Diff')[['Team', 'Home_Win_Rate', 'Away_Win_Rate', 'Home_Away_Diff']]) # 客场表现反而更好的队伍 print("\n客场表现优于主场的队伍:") print(team_stats.nsmallest(5, 'Home_Away_Diff')[['Team', 'Home_Win_Rate', 'Away_Win_Rate', 'Home_Away_Diff']])
完整代码合并(直接运行)
如果你有 pandas, matplotlib, seaborn,可以直接复制以下精简版脚本:
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 假设 df 是你读取的DataFrame
# df = pd.read_csv('your_file.csv')
# 1. 计算胜负
df['Home_Win'] = (df['Home_Score'] > df['Away_Score']).astype(int)
df['Draw'] = (df['Home_Score'] == df['Away_Score']).astype(int)
df['Away_Win'] = (df['Home_Score'] < df['Away_Score']).astype(int)
# 2. 统计所有球队
all_teams = pd.unique(df[['Home_Team', 'Away_Team']].values.ravel())
rows = []
for team in all_teams:
h = df[df['Home_Team'] == team]
a = df[df['Away_Team'] == team]
h_wins = h['Home_Win'].sum()
a_wins = a['Away_Win'].sum()
h_rate = h_wins / len(h) * 100 if len(h) else 0
a_rate = a_wins / len(a) * 100 if len(a) else 0
rows.append({
'Team': team,
'Home_Rate': round(h_rate, 1),
'Away_Rate': round(a_rate, 1),
'Diff': round(h_rate - a_rate, 1)
})
stats = pd.DataFrame(rows)
print(stats.sort_values('Diff', ascending=False))
# 3. 可视化
plt.figure(figsize=(10, 6))
sns.scatterplot(data=stats, x='Home_Rate', y='Away_Rate', s=100)
plt.plot([0, 100], [0, 100], 'k--', alpha=0.6)
for _, r in stats.iterrows():
plt.text(r['Home_Rate']+0.8, r['Away_Rate']+0.8, r['Team'], fontsize=7)
plt.xlabel('主场胜率 (%)')
plt.ylabel('客场胜率 (%)')'各队主客场胜率分布')
plt.grid(True, ls='--', alpha=0.5)
plt.tight_layout()
plt.show()
如果数据格式不同(比如没有“主客场”字段),或者想进一步做赛前预测(如用逻辑回归预测主队获胜概率),可以告诉我你的具体数据结构,我可以帮你调整代码。