使用Pandas DataFrame时自定义Max函数触发ValueError的问题排查
问题分析与解决方案
首先咱们得搞清楚为什么Sum函数能正常工作,而Max函数却报错:
为什么Sum没问题?
你的Sum函数里用了h+l+c,这里的h、l、c都是Pandas的Series对象。Pandas对Series重载了加法运算符,它会自动做逐元素运算——也就是把每一行对应的high、low、close值分别相加,最后返回一个新的Series,刚好能直接赋值给df['Sum']。
Max函数的问题出在哪?
你用的是Python内置的max()函数,这个函数是用来比较单个值大小的。当你把三个Series传给它时,它会尝试判断每个Series的"真值"(比如整个Series是不是为空、有没有非零值),但Pandas的Series没有统一的布尔真值(因为一个Series里有多个元素,没法直接说整个Series是True还是False),所以就抛出了ValueError: The truth value of a Series is ambiguous这个错误。
简单说:内置max()不认识Pandas的Series,它不知道你要的是逐行取最大值,还是整个Series的最大值。
解决方法
方法1:用Pandas原生的逐行最大值方法
这是最简洁高效的方式,直接利用Pandas的max()方法并指定axis=1(表示按行计算):
df['Max'] = df[['high', 'low', 'close']].max(axis=1)
方法2:用apply把自定义函数应用到每一行
如果你一定要用自定义的Max函数,可以用df.apply(),把函数作用到每一行上,这样函数接收的就是每行的单个数值,而不是整个Series:
def Max(h, l, c): return max(h, l, c) df['Max'] = df.apply(lambda row: Max(row['high'], row['low'], row['close']), axis=1)
方法3:使用Pandas的numpy.maximum.reduce
如果你想更底层一点,也可以借助NumPy的广播特性来实现逐行取最大:
import numpy as np df['Max'] = np.maximum.reduce([df['high'], df['low'], df['close']])
测试一下这些方法,你就能得到和Sum列类似的正常结果啦:
high low close Sum Max date 2018-01-23 80.65 78.25 79.45 238.35 80.65 2018-01-24 81.65 79.50 80.50 241.65 81.65 2018-01-25 81.70 80.25 81.10 243.05 81.70 2018-01-26 81.25 78.25 78.75 238.25 81.25 2018-01-29 70.95 62.25 64.15 197.35 70.95
内容的提问来源于stack exchange,提问作者w2kpro
相关产品推荐
相关产品推荐

