Pandas比较DataFrame行与前一行值时触发ValueError问题求助
问题描述
尝试通过比较当前行与前一行的值创建新列时触发ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(),已确认所有列数据类型为float64但错误仍存在。
相关代码
cols=['High', 'Low', 'Open', 'Volume', "Adj Close"] df = df.drop(columns = cols) df['EMA60'] = df['Close'].ewm(span=60, adjust=False).mean() df['EMA100'] = df['Close'].ewm(span=100, adjust=False).mean() df['MACD_60_100'] = df['EMA60'] - df['EMA100'] df['SIGNAL_60_100'] = df['MACD_60_100'].ewm(span=9, adjust=False).mean() df['HIST_60_100'] = df['MACD_60_100'] - df['SIGNAL_60_100'] # Histogram df = df.iloc[1: , :] # Delete first row in DF as it contains NAN print(df.dtypes) print (df) if df[df['HIST_60_100'] > df['HIST_60_100'].shift(+1)]: # check if the valus is > previous row value df['COLOR-60-100'] = "GREEN" else: df['COLOR-60-100'] = "RED" print(df.to_string())
报错信息
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) ~\AppData\Local\Temp/ipykernel_10972/77395577.py in <module> 32 33 ---> 34 get_data_from_yahoo(symbol+".NS") 35 36 # df.to_excel(sheetXls, index=False) ~\AppData\Local\Temp/ipykernel_10972/520355426.py in get_data_from_yahoo(symbol, interval, start, end) 26 print(df.dtypes) 27 print (df) ---> 28 if df[df['HIST_60_100'] > df['HIST_60_100'].shift(+1)]: 29 df['COLOR-60-100'] = "GREEN" 30 else: ~\AppData\Roaming\Python\Python39\site-packages\pandas\core\generic.py in __nonzero__(self) 1327 1328 def __nonzero__(self): -> 1329 raise ValueError( 1330 f"The truth value of a {type(self).__name__} is ambiguous. " 1331 "Use a.empty, a.bool(), a.item(), a.any() or a.all()." ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
错误原因
df[df['HIST_60_100'] > df['HIST_60_100'].shift(+1)]返回的是过滤后的DataFrame对象,而非单个布尔值。Python的if语句只能判断单个布尔值,无法直接判断整个DataFrame的真假,因此触发歧义错误。
你的逻辑是想对每一行单独判断:如果当前行的HIST_60_100大于上一行,就标记为"GREEN",否则"RED",但当前写法是尝试把整个DataFrame放进if条件,不符合语法要求。
解决方案
可以用以下两种方式实现需求:
方法1:使用numpy.where(推荐)
通过向量化操作直接生成新列,效率更高:
import numpy as np # 生成布尔序列:当前行 > 上一行 condition = df['HIST_60_100'] > df['HIST_60_100'].shift(1) # 根据条件赋值,shift后第一行结果为NaN,会被视为False标记为RED df['COLOR-60-100'] = np.where(condition, "GREEN", "RED")
方法2:使用apply逐行处理
如果需要更复杂的逻辑,也可以用apply遍历每一行:
import numpy as np def determine_color(row, df): prev_val = df.loc[row.name - 1, 'HIST_60_100'] if row.name > 0 else np.nan return "GREEN" if row['HIST_60_100'] > prev_val else "RED" df['COLOR-60-100'] = df.apply(determine_color, args=(df,), axis=1)
若需对第一行做特殊标记,可单独修改对应逻辑。
内容的提问来源于stack exchange,提问作者Ashish
相关产品推荐
相关产品推荐

