如何在Pandas中避免除零错误并计算指定衍生列?
解决Pandas中Series布尔判断的歧义错误
问题场景
现有如下DataFrame:
A B 0 2 8 1 3 1 2 5 0 3 -1 2 4 2 1 5 3 0 .. .. ..
需要计算((df['B']-df['A'])/df['B'])*100并生成新列D%,尝试用以下代码避免除零错误时触发报错:
if data['B']!=0: data['D%']=((data['B']-data['A'])/data['B'])*100 else: data['D%']=np.nan
报错信息:
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
解决方案
方法1:使用np.where(推荐,向量化操作效率高)
利用np.where对每个元素做条件判断,满足条件时计算目标值,否则赋值np.nan:
import numpy as np import pandas as pd data['D%'] = np.where(data['B'] != 0, ((data['B'] - data['A']) / data['B']) * 100, np.nan)
方法2:使用Pandas的mask方法
mask会将满足指定条件的位置替换为设定值,这里把B=0的行对应的D%替换为np.nan:
# 先计算所有值,再替换不符合条件的行 data['D%'] = ((data['B'] - data['A']) / data['B']) * 100 data['D%'] = data['D%'].mask(data['B'] == 0, np.nan) # 也可以一步完成 data['D%'] = (((data['B'] - data['A']) / data['B']) * 100).mask(data['B'] == 0, np.nan)
方法3:使用apply逐行处理(仅适用于小型数据集)
如果数据集规模很小,可通过apply逐行判断,但该方法性能远低于向量化操作,不推荐用于大数据集:
data['D%'] = data.apply(lambda row: ((row['B'] - row['A']) / row['B']) * 100 if row['B'] != 0 else np.nan, axis=1)
错误原因
原代码直接用if data['B']!=0对整个Series做布尔判断,返回的是一个布尔值组成的Series,而if语句需要单个布尔值来判断分支,Pandas无法确定你是要判断所有元素满足条件、还是至少一个满足,因此抛出歧义错误。必须使用向量化的条件处理方法来逐个处理每个元素。
内容的提问来源于stack exchange,提问作者Javier
相关产品推荐
相关产品推荐

