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

Python ValueError形状不匹配问题修复及代码解析

解决ValueError:球队进球/失球统计代码的问题

首先,咱们来拆解你遇到的错误:

ValueError: Shape of passed values is (20, 32), indices imply (20, 38)

这个错误的核心是数据长度不匹配:你创建DataFrame时,传入的每支球队的进球/失球列表长度是32,但代码硬指定了38个索引(对应1到38轮比赛),两者无法对齐,所以抛出了这个错误。


先给你解释原代码的逻辑

get_goals_scored 函数(获取累计进球)

  1. 初始化球队字典:通过分组主场球队,创建以球队名为键的空字典,用来存储每轮的进球数
  2. 遍历比赛数据:对每一场比赛,把主场球队的当场进球(FTHG,Full Time Home Goals)加到对应球队的列表,客场球队的当场进球(FTAG,Full Time Away Goals)也加到对应列表
  3. 创建累计进球DataFrame:硬编码了1到38轮的索引,转置后行是球队、列是比赛周;然后添加初始值0的列,通过循环累加得到截至每一轮的总进球数

get_goals_conceded 函数(获取累计失球)

逻辑和进球统计几乎一致,只是统计的是失球:

  • 主场球队的失球 = 客场球队的进球(FTAG)
  • 客场球队的失球 = 主场球队的进球(FTHG)

错误原因 & 修复方案

错误根源

原代码默认联赛是38轮(比如英超),但你的数据源playing_stat里,每支球队实际只打了32场比赛(可能是赛季未结束、数据只截取了部分轮次),硬编码的38轮索引和实际数据长度不匹配,导致报错。

修复后的代码(动态适配数据长度)

我们把硬编码的38改成动态获取实际比赛轮次,同时优化了球队获取逻辑(避免遗漏球队):

累计进球函数

import pandas as pd

def get_goals_scored(playing_stat):
    # 初始化球队字典:获取所有出现过的球队(主场+客场)
    teams = {team: [] for team in pd.concat([playing_stat['HomeTeam'], playing_stat['AwayTeam']]).unique()}
    
    # 遍历每场比赛,记录各队当场进球
    for _, row in playing_stat.iterrows():
        home_team = row['HomeTeam']
        away_team = row['AwayTeam']
        home_goals = row['FTHG']
        away_goals = row['FTAG']
        
        teams[home_team].append(home_goals)
        teams[away_team].append(away_goals)
    
    # 动态获取实际比赛轮次(取任意一支球队的比赛场次)
    num_matchweeks = len(next(iter(teams.values())))
    # 创建DataFrame,索引对应实际轮次
    goals_scored = pd.DataFrame(data=teams, index=range(1, num_matchweeks + 1)).T
    
    # 添加初始累计列(0轮时进球为0)
    goals_scored[0] = 0
    # 按列排序,确保轮次顺序正确
    goals_scored = goals_scored.sort_index(axis=1)
    
    # 计算截至每一轮的累计进球
    for week in range(1, num_matchweeks + 1):
        goals_scored[week] = goals_scored[week] + goals_scored[week - 1]
    
    return goals_scored

累计失球函数

def get_goals_conceded(playing_stat):
    # 初始化球队字典:获取所有出现过的球队(主场+客场)
    teams = {team: [] for team in pd.concat([playing_stat['HomeTeam'], playing_stat['AwayTeam']]).unique()}
    
    # 遍历每场比赛,记录各队当场失球
    for _, row in playing_stat.iterrows():
        home_team = row['HomeTeam']
        away_team = row['AwayTeam']
        # 主场失球=客场进球,客场失球=主场进球
        home_conceded = row['FTAG']
        away_conceded = row['FTHG']
        
        teams[home_team].append(home_conceded)
        teams[away_team].append(away_conceded)
    
    # 动态获取实际比赛轮次
    num_matchweeks = len(next(iter(teams.values())))
    goals_conceded = pd.DataFrame(data=teams, index=range(1, num_matchweeks + 1)).T
    
    # 添加初始累计列(0轮时失球为0)
    goals_conceded[0] = 0
    goals_conceded = goals_conceded.sort_index(axis=1)
    
    # 计算截至每一轮的累计失球
    for week in range(1, num_matchweeks + 1):
        goals_conceded[week] = goals_conceded[week] + goals_conceded[week - 1]
    
    return goals_conceded

关键修改点

  1. 动态获取轮次:不再硬写38,而是从球队的比赛列表长度中获取实际轮次,适配任何长度的数据源
  2. 更严谨的球队获取:用concat获取所有主场+客场球队,避免遗漏只出现在客场的球队(虽然联赛中很少见,但更鲁棒)
  3. 用iterrows()遍历:比原代码的iloc[i]更易读,也更符合pandas的常规写法
  4. 列排序:确保轮次从0到实际最大轮次的顺序正确,避免累加时出错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:26:22