使用Numpy向量化替代循环时Pandas代码报错:Draws列全为None
问题排查:Pandas Draws列全为None的原因与修复方案
兄弟,你碰到的Draws列全是None的问题,核心原因非常直观——你的soc_iter函数没有返回任何值,Python中没有return语句的函数默认返回None,所以最后执行leaguedf['Draws']=soc_iter(...)时,整列就被赋值成None了。
另外还有个小细节:你调用函数时传入的是.values(比如leaguedf['HomeTeam'].values),这会把Pandas Series转换成numpy数组,丢失了索引信息,后续用loc操作时容易出问题,直接传入Series会更稳妥。
下面给你两种修复方案,按需选择:
方案一:让函数返回处理后的结果(推荐,更规范)
这种方式不依赖全局变量,函数只负责计算并返回结果,代码更健壮、可复用:
import pandas as pd data = {'HomeTeam':['Burnley','Crystal Palace','Everton','Hull','Man City','Middlesbrough','Southampton', 'Arsenal','Bournemouth','Chelsea','Man United','Burnley','Leicester','Stoke'], 'AwayTeam':['Swansea','West Brom','Tottenham','Leicester','Sunderland','Stoke','Watford','Liverpool','Man United', 'West Ham','Southampton','Liverpool','Arsenal','Man City'], 'FTR': ['A','A','D','H','H','D','D','A','A','H','H','H','D','A']} leaguedf = pd.DataFrame(data) def soc_iter(TEAM, home, away, ftr): # 初始化一个全为'No_Game'的Series,保留原索引 draws = pd.Series(['No_Game'] * len(home), index=home.index) # 标记该球队参与的平局场次 draws.loc[((home == TEAM) & (ftr == 'D')) | ((away == TEAM) & (ftr == 'D'))] = 'Draw' # 标记该球队参与的非平局场次 draws.loc[((home == TEAM) & (ftr != 'D')) | ((away == TEAM) & (ftr != 'D'))] = 'No_Draw' # 返回处理好的Series return draws # 调用函数并赋值给Draws列 leaguedf['Draws'] = soc_iter('Arsenal', leaguedf['HomeTeam'], leaguedf['AwayTeam'], leaguedf['FTR']) leaguedf
方案二:直接让函数修改全局DataFrame(快速修复,不推荐)
如果只是想快速验证结果,可以让函数直接操作全局的leaguedf,调用后不需要赋值:
import pandas as pd data = {'HomeTeam':['Burnley','Crystal Palace','Everton','Hull','Man City','Middlesbrough','Southampton', 'Arsenal','Bournemouth','Chelsea','Man United','Burnley','Leicester','Stoke'], 'AwayTeam':['Swansea','West Brom','Tottenham','Leicester','Sunderland','Stoke','Watford','Liverpool','Man United', 'West Ham','Southampton','Liverpool','Arsenal','Man City'], 'FTR': ['A','A','D','H','H','D','D','A','A','H','H','H','D','A']} leaguedf = pd.DataFrame(data) def soc_iter(TEAM): # 初始化Draws列 leaguedf['Draws'] = 'No_Game' # 标记平局场次 leaguedf.loc[((leaguedf['HomeTeam'] == TEAM) & (leaguedf['FTR'] == 'D')) | ((leaguedf['AwayTeam'] == TEAM) & (leaguedf['FTR'] == 'D')), 'Draws'] = 'Draw' # 标记非平局场次 leaguedf.loc[((leaguedf['HomeTeam'] == TEAM) & (leaguedf['FTR'] != 'D')) | ((leaguedf['AwayTeam'] == TEAM) & (leaguedf['FTR'] != 'D')), 'Draws'] = 'No_Draw' # 直接调用函数,无需赋值 soc_iter('Arsenal') leaguedf
执行任意一种方案后,你就能看到Draws列正确显示为Draw、No_Draw或No_Game了。
内容的提问来源于stack exchange,提问作者jack homareau
相关产品推荐
相关产品推荐

