You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python报错求助:index 1 is out of bounds for axis 1 with size 0

问题与解决方案

问题详情

在对DataFrame执行for循环计算球队对战胜率时,循环执行427,942行后触发报错:

index 1 is out of bounds for axis 1 with size 0

相关代码:

自定义函数部分

outcome = []

def get_matchup(team_a_input, team_b_input, season_input):
    team_a = team_a_input
    team_b = team_b_input
    season = season_input

    team_a_stats = df.loc[(df.TeamID == team_a) & (df.Season == season)]
    team_a_results = team_a_stats['Result']
    team_a_stats = team_a_stats.drop(['Result'], axis=1)

    team_b_stats = df.loc[(df.TeamID == team_b) & (df.Season == season)]
    team_b_results = team_b_stats['Result']
    team_b_stats = team_b_stats.drop(['Result'], axis=1)

    probs_team_a = loaded_model.predict_proba(team_a_stats)
    probs_team_a = probs_team_a[:,1]
    loss_team_a = brier_score_loss(team_a_results, probs_team_a)

    probs_team_b = loaded_model.predict_proba(team_b_stats)
    probs_team_b = probs_team_b[:,1]
    loss_team_b = brier_score_loss(team_b_results, probs_team_b)
    
    team_a_win_prob = probs_team_a.mean()/(probs_team_a.mean()+probs_team_b.mean())
    team_b_win_prob = probs_team_b.mean()/(probs_team_a.mean()+probs_team_b.mean())

    outcome.append(team_a_win_prob)

循环执行部分

Season = []
ATeam = []
BTeam = []


for index, row in SampleSubmissionWarmup_df.iterrows():
    Season = SampleSubmissionWarmup_df.Season
    ATeam = SampleSubmissionWarmup_df.ATeam
    BTeam = SampleSubmissionWarmup_df.BTeam
    get_matchup(row['ATeam'],row['BTeam'],row['Season'])

需求是对每行的两支球队调用机器学习模型计算对战获胜概率,将结果存入列表后添加至DataFrame导出,但执行中出现上述报错,同时需要代码优化建议。

错误原因分析

报错index 1 is out of bounds for axis 1 with size 0本质是:

  • 当某行的(TeamID, Season)组合在df中没有匹配数据时,team_a_stats或team_b_stats会变成空DataFrame
  • 空DataFrame传入predict_proba后,模型返回的结果数组维度为(0, n_classes)或直接为空,此时执行[:,1]索引就会触发越界错误

修复方案

在自定义函数中添加空值判断,处理无匹配数据的情况:

outcome = []

def get_matchup(team_a, team_b, season):
    # 获取球队A数据并处理
    team_a_stats = df.loc[(df.TeamID == team_a) & (df.Season == season)]
    if team_a_stats.empty:
        # 无数据时的默认处理,比如赋值0.5或跳过
        outcome.append(0.5)
        return
    team_a_results = team_a_stats['Result']
    team_a_stats = team_a_stats.drop(['Result'], axis=1)

    # 获取球队B数据并处理
    team_b_stats = df.loc[(df.TeamID == team_b) & (df.Season == season)]
    if team_b_stats.empty:
        outcome.append(0.5)
        return
    team_b_results = team_b_stats['Result']
    team_b_stats = team_b_stats.drop(['Result'], axis=1)

    # 计算概率与损失
    probs_team_a = loaded_model.predict_proba(team_a_stats)[:,1]
    loss_team_a = brier_score_loss(team_a_results, probs_team_a)

    probs_team_b = loaded_model.predict_proba(team_b_stats)[:,1]
    loss_team_b = brier_score_loss(team_b_results, probs_team_b)
    
    # 计算对战胜率,处理分母为0的情况
    mean_a = probs_team_a.mean()
    mean_b = probs_team_b.mean()
    team_a_win_prob = mean_a / (mean_a + mean_b) if (mean_a + mean_b) != 0 else 0.5
    outcome.append(team_a_win_prob)

代码优化建议

1. 移除循环中的冗余代码

原循环里的Season = SampleSubmissionWarmup_df.Season等三行完全冗余,每次循环都把整个列赋值给变量,毫无作用,直接删除:

for index, row in SampleSubmissionWarmup_df.iterrows():
    get_matchup(row['ATeam'], row['BTeam'], row['Season'])

2. 替换iterrows()为apply提升效率

iterrows()遍历40多万行效率极低,改用DataFrame.apply实现向量化操作,同时修改函数让它直接返回结果,无需手动维护列表:

def get_matchup(team_a, team_b, season):
    team_a_stats = df.loc[(df.TeamID == team_a) & (df.Season == season)]
    if team_a_stats.empty:
        return 0.5
    team_a_results = team_a_stats['Result']
    team_a_stats = team_a_stats.drop(['Result'], axis=1)

    team_b_stats = df.loc[(df.TeamID == team_b) & (df.Season == season)]
    if team_b_stats.empty:
        return 0.5
    team_b_results = team_b_stats['Result']
    team_b_stats = team_b_stats.drop(['Result'], axis=1)

    probs_team_a = loaded_model.predict_proba(team_a_stats)[:,1]
    probs_team_b = loaded_model.predict_proba(team_b_stats)[:,1]
    
    mean_a = probs_team_a.mean()
    mean_b = probs_team_b.mean()
    return mean_a / (mean_a + mean_b) if (mean_a + mean_b) != 0 else 0.5

# 直接生成结果列
SampleSubmissionWarmup_df['TeamA_Win_Prob'] = SampleSubmissionWarmup_df.apply(
    lambda row: get_matchup(row['ATeam'], row['BTeam'], row['Season']),
    axis=1
)

3. 预计算球队赛季统计值,彻底抛弃循环

利用pandas分组聚合和合并操作,完全避免循环,性能提升几个数量级:

# 预计算每个球队每个赛季的平均获胜概率
df['Probs'] = loaded_model.predict_proba(df.drop('Result', axis=1))[:,1]
team_season_probs = df.groupby(['TeamID', 'Season'])['Probs'].mean().reset_index()

# 合并A队数据
SampleSubmissionWarmup_df = SampleSubmissionWarmup_df.merge(
    team_season_probs, left_on=['ATeam', 'Season'], right_on=['TeamID', 'Season'], how='left'
).rename(columns={'Probs': 'ATeam_Prob'}).drop('TeamID', axis=1)

# 合并B队数据
SampleSubmissionWarmup_df = SampleSubmissionWarmup_df.merge(
    team_season_probs, left_on=['BTeam', 'Season'], right_on=['TeamID', 'Season'], how='left'
).rename(columns={'Probs': 'BTeam_Prob'}).drop('TeamID', axis=1)

# 计算对战胜率,处理空值和分母为0的情况
SampleSubmissionWarmup_df['TeamA_Win_Prob'] = SampleSubmissionWarmup_df.apply(
    lambda row: row['ATeam_Prob']/(row['ATeam_Prob']+row['BTeam_Prob']) 
    if pd.notna(row['ATeam_Prob']) and pd.notna(row['BTeam_Prob']) and (row['ATeam_Prob']+row['BTeam_Prob']) !=0 
    else 0.5,
    axis=1
)

4. 移除冗余变量

原函数中team_a = team_a_input这类赋值完全多余,直接使用参数即可,减少代码复杂度。


内容的提问来源于stack exchange,提问作者WooTeenie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 23:08:22