如何基于Pandas DataFrame两列值逐行执行函数并解决真值歧义报错
解决Pandas逐行计算生长度日(GDD)的错误问题
问题背景
我有一个包含Date、Minimum Temp、Maximum Temp列的Pandas DataFrame,需要按规则逐行处理:
- 当日最高温大于86时,用最高温和最低温计算平均温度;
- 否则用86和最低温计算平均温度。
再基于该均值计算生长度日(GDD)并收集结果。但运行以下代码时出现错误:
#Function defining how to obtain the mean based on max temp def MeanTemp(T_min, T_max): if T_max < 86: mean = np.mean(T_max, T_min) else: mean = np.mean(86, T_min) return mean #Function that will use the mean from the MeanTemp function def GrowingDegreeDays(mean,base): if mean > base: GDD = mean-base else: GDD = 0 #For each row in my dataframe, I want it to perform these two functions for Date in df: mean = MeanTemp(T_min, T_max) GrowingDegreeDays(mean,50)
错误信息:
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
我推测是函数在处理整列而非单行值导致的,作为编程新手,希望得到简单易懂的解决方案,如何让函数处理DataFrame的单行值?
错误原因
你猜的没错:
- 循环
for Date in df实际是遍历DataFrame的列名,而非逐行遍历; - 调用
MeanTemp(T_min, T_max)时,传入的是整列的Series对象,不是单行的数值; - 用
if T_max < 86判断一个Series时,会返回一组布尔值,Pandas无法确定整个Series的“真假”,因此抛出歧义错误; np.mean用法错误,它需要传入数组(比如np.mean([a,b])),而非两个单独参数;GrowingDegreeDays函数没有返回值,就算计算了GDD也无法收集结果。
解决方案
方法1:用df.apply逐行处理(新手友好)
先修正函数问题,再用apply逐行调用:
import numpy as np import pandas as pd # 修正后的平均温度计算函数 def MeanTemp(row): T_min = row['Minimum Temp'] T_max = row['Maximum Temp'] if T_max > 86: mean = np.mean([T_max, T_min]) else: mean = np.mean([86, T_min]) return mean # 修正后的生长度日计算函数 def GrowingDegreeDays(mean, base): return mean - base if mean > base else 0 # 1. 计算每行的平均温度,新增一列 df['Mean Temp'] = df.apply(MeanTemp, axis=1) # 2. 计算每行的GDD,新增一列 df['GDD'] = df['Mean Temp'].apply(lambda x: GrowingDegreeDays(x, 50))
说明:
df.apply(..., axis=1)表示逐行处理,每一行会作为参数传给MeanTemp函数;- 修正了
np.mean的调用方式,传入包含两个值的列表; - 给
GrowingDegreeDays加上return语句,确保返回计算结果; - 用lambda函数把每行的平均温度传给GDD计算函数。
方法2:矢量化操作(更高效,适合大数据量)
Pandas推荐用矢量化操作代替逐行循环,速度更快:
import numpy as np import pandas as pd # 计算平均温度:用np.where实现条件判断 df['Mean Temp'] = np.where( df['Maximum Temp'] > 86, (df['Maximum Temp'] + df['Minimum Temp']) / 2, (86 + df['Minimum Temp']) / 2 ) # 计算GDD:同样用np.where df['GDD'] = np.where( df['Mean Temp'] > 50, df['Mean Temp'] - 50, 0 )
说明:
np.where(条件, 满足条件时的值, 不满足条件时的值)可直接对整列进行条件计算,无需逐行遍历;- 用算术平均代替
np.mean,结果一致且更简洁。
内容的提问来源于stack exchange,提问作者Manta Raych
相关产品推荐
相关产品推荐

