如何解决Pandas中分数字符串转浮点数的ValueError错误?
解决赔率列分数转浮点值的报错问题
你有如下结构的DataFrame:
df.head() country league home_odds draw_odds away_odds datetime home_team away_team home_score away_score 381084 Iceland League Cup 167/50 329/100 63/100 2016-02-16 19:15:00 Kopavogur Vikingur Reykjavik 0 1 381085 Iceland League Cup 463/100 173/50 47/100 2016-02-14 21:15:00 Fram Stjarnan 0 3 381086 Iceland League Cup 9/25 99/25 303/50 2016-02-14 19:15:00 KR Reykjavik Haukar 1 1 381087 Iceland League Cup 9/25 393/100 611/100 2016-02-14 19:00:00 Thor Akureyri Leiknir F. 5 0 381088 Iceland League Cup 11/25 353/100 251/50 2016-02-14 17:00:00 Akranes Grindavik 5 0
应用了以下转换函数:
def convert(s): if '/' in str(s): # is a fraction num, den = s.split('/') return 1 + (int(num) / int(den)) else: return s.astype(float) odds_cols = ['home_odds', 'draw_odds', 'away_odds'] df[odds_cols] = df[odds_cols].apply(convert)
执行时出现如下错误:
Traceback (most recent call last): File "C:\Users\user\AppData\Roaming\JetBrains\PyCharmCE2022.2\scratches\scratch_2.py", line 70, in df[odds_cols] = df[odds_cols].apply(convert).... return arr.astype(dtype, copy=True) ValueError: could not convert string to float: '167/50'
错误原因
df[odds_cols].apply(convert)默认按列处理数据,也就是convert函数接收的是整个Series对象,而非单个单元格的字符串值:
- 判断
'/' in str(s)时,str(s)会输出整个列的字符串表示,无法正确识别单个元素的分数格式 - 后续的
split('/')无法对Series执行,最后return s.astype(float)时,列中仍有'167/50'这类字符串,自然无法转换为浮点型,触发报错
解决方法
方法1:用applymap逐元素处理
将apply替换为applymap,让函数作用到每个单元格元素上,同时增加异常处理避免意外格式报错:
def convert(s): s_str = str(s).strip() if '/' in s_str: num, den = s_str.split('/') try: return 1 + (int(num) / int(den)) except (ValueError, ZeroDivisionError): return None else: try: return float(s_str) except ValueError: return None odds_cols = ['home_odds', 'draw_odds', 'away_odds'] df[odds_cols] = df[odds_cols].applymap(convert)
方法2:向量化批量处理(更高效)
如果所有赔率都是分数格式,可利用pandas字符串方法批量处理,性能优于逐元素遍历:
odds_cols = ['home_odds', 'draw_odds', 'away_odds'] # 拆分所有赔率列的分子分母 split_df = df[odds_cols].apply(lambda x: x.str.split('/', expand=True).astype(int)) # 计算转换后的值:1 + 分子/分母 df[odds_cols] = 1 + split_df.xs(0, axis=1) / split_df.xs(1, axis=1)
内容的提问来源于stack exchange,提问作者PyNoob
相关产品推荐
相关产品推荐

