解决GeoDataFrame真值歧义错误:iterrows条件赋值问题修复
基于行级条件赋值触发ValueError的修复方案
问题背景
需根据merge_c['Actual methane']的数值创建新列,尝试用iterrows遍历每行并通过if条件赋值,运行时触发ValueError,提示GeoDataFrame的真值不明确。
原代码
merge_c = merge_c.sort_values(by="2019-CON", ascending=False) merge_c.head(21) merge_c['Actual methane'] = merge_c['2019-CON'] - merge_c['total_methane_mean_TWh'] for index, row in merge_c.iterrows(): if merge_c[merge_c['Actual methane'] > 0]: merge_c['bio_met_min'] = 0 merge_c['lower_bound_ng'] = merge_c['Actual methane'] *0.016 merge_c['higher_bound_ng'] = merge_c['Actual methane'][i] *0.056 merge_c['lower_bound_bio'] = merge_c['total_methane_mean_TWh'] *0.059 merge_c['higher_bound_bio'] = merge_c['total_methane_mean_TWh'] *0.0604 merge_c['lower_total'] = merge_c['lower_bound_ng'] + merge_c['lower_bound_bio'] merge_c['higher_total'] = merge_c['higher_bound_ng'][i] + merge_c['higher_bound_bio'] merge_c['lower_total_ng'] = merge_c['2019-CON'] *0.016 merge_c['higher_total_ng'] = merge_c['2019-CON']*0.056 else: merge_c['bio_met_min'] = merge_c['total_methane_mean_TWh'] + merge_c['Actual methane'] merge_c['lower_bound_ng'] = 0 merge_c['higher_bound_ng'] = 0 merge_c['lower_bound_bio'] = 0 merge_c['higher_bound_bio'] = 0 merge_c['lower_total'] = merge_c['bio_met_min']*0.051 merge_c['higher_total'] = merge_c['bio_met_min'] *0.053 merge_c['lower_total_ng']= merge_c['2019-CON'] *0.008 merge_c['higher_total_ng'] = merge_c['2019-CON'] *0.022
错误信息
ValueError Traceback (most recent call last) <ipython-input-19-65d61ab401ac> in <module> 4 merge_c['Actual methane'] = merge_c['2019-CON'] - merge_c['total_methane_mean_TWh'] 5 for index, row in merge_c.iterrows(): ----> 6 if merge_c[merge_c['Actual methane'] > 0]: -> 1442 raise ValueError( 1443 f"The truth value of a {type(self).__name__} is ambiguous. " 1444 "Use a.empty, a.bool(), a.item(), a.any() or a.all()." ValueError: The truth value of a GeoDataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
错误原因
- if条件判断错误:
if merge_c[merge_c['Actual methane'] > 0]会生成一个子GeoDataFrame,if语句无法直接判断整个DataFrame的真假,导致真值不明确的错误。 - 变量误用:代码中使用了未定义的变量
i,应该用当前遍历的index。 - 列赋值逻辑错误:循环中直接对整列赋值(如
merge_c['bio_met_min'] = 0),会覆盖所有行的数据,而非仅当前行。
修复方案
方案1:修正iterrows遍历逻辑(不推荐,效率低)
若坚持用iterrows,需通过loc定位当前行进行赋值,避免整列覆盖:
merge_c = merge_c.sort_values(by="2019-CON", ascending=False) merge_c['Actual methane'] = merge_c['2019-CON'] - merge_c['total_methane_mean_TWh'] # 先初始化所有新列,避免索引缺失问题 new_cols = ['bio_met_min', 'lower_bound_ng', 'higher_bound_ng', 'lower_bound_bio', 'higher_bound_bio', 'lower_total', 'higher_total', 'lower_total_ng', 'higher_total_ng'] merge_c[new_cols] = 0 for index, row in merge_c.iterrows(): if row['Actual methane'] > 0: # 针对当前行赋值 merge_c.loc[index, 'bio_met_min'] = 0 merge_c.loc[index, 'lower_bound_ng'] = row['Actual methane'] * 0.016 merge_c.loc[index, 'higher_bound_ng'] = row['Actual methane'] * 0.056 merge_c.loc[index, 'lower_bound_bio'] = row['total_methane_mean_TWh'] * 0.059 merge_c.loc[index, 'higher_bound_bio'] = row['total_methane_mean_TWh'] * 0.0604 merge_c.loc[index, 'lower_total'] = merge_c.loc[index, 'lower_bound_ng'] + merge_c.loc[index, 'lower_bound_bio'] merge_c.loc[index, 'higher_total'] = merge_c.loc[index, 'higher_bound_ng'] + merge_c.loc[index, 'higher_bound_bio'] merge_c.loc[index, 'lower_total_ng'] = row['2019-CON'] * 0.016 merge_c.loc[index, 'higher_total_ng'] = row['2019-CON'] * 0.056 else: bio_met_min_val = row['total_methane_mean_TWh'] + row['Actual methane'] merge_c.loc[index, 'bio_met_min'] = bio_met_min_val merge_c.loc[index, ['lower_bound_ng', 'higher_bound_ng', 'lower_bound_bio', 'higher_bound_bio']] = 0 merge_c.loc[index, 'lower_total'] = bio_met_min_val * 0.051 merge_c.loc[index, 'higher_total'] = bio_met_min_val * 0.053 merge_c.loc[index, 'lower_total_ng'] = row['2019-CON'] * 0.008 merge_c.loc[index, 'higher_total_ng'] = row['2019-CON'] * 0.022
方案2:使用向量化操作(推荐,效率极高)
Pandas原生支持向量化操作,无需循环,通过布尔索引直接批量赋值,性能远超iterrows:
merge_c = merge_c.sort_values(by="2019-CON", ascending=False) merge_c['Actual methane'] = merge_c['2019-CON'] - merge_c['total_methane_mean_TWh'] # 定义布尔条件:Actual methane大于0的行 mask = merge_c['Actual methane'] > 0 # 给满足条件的行赋值 merge_c.loc[mask, 'bio_met_min'] = 0 merge_c.loc[mask, 'lower_bound_ng'] = merge_c.loc[mask, 'Actual methane'] * 0.016 merge_c.loc[mask, 'higher_bound_ng'] = merge_c.loc[mask, 'Actual methane'] * 0.056 merge_c.loc[mask, 'lower_bound_bio'] = merge_c.loc[mask, 'total_methane_mean_TWh'] * 0.059 merge_c.loc[mask, 'higher_bound_bio'] = merge_c.loc[mask, 'total_methane_mean_TWh'] * 0.0604 merge_c.loc[mask, 'lower_total'] = merge_c.loc[mask, 'lower_bound_ng'] + merge_c.loc[mask, 'lower_bound_bio'] merge_c.loc[mask, 'higher_total'] = merge_c.loc[mask, 'higher_bound_ng'] + merge_c.loc[mask, 'higher_bound_bio'] merge_c.loc[mask, 'lower_total_ng'] = merge_c.loc[mask, '2019-CON'] * 0.016 merge_c.loc[mask, 'higher_total_ng'] = merge_c.loc[mask, '2019-CON'] * 0.056 # 给不满足条件的行赋值(~mask表示取反) merge_c.loc[~mask, 'bio_met_min'] = merge_c.loc[~mask, 'total_methane_mean_TWh'] + merge_c.loc[~mask, 'Actual methane'] merge_c.loc[~mask, ['lower_bound_ng', 'higher_bound_ng', 'lower_bound_bio', 'higher_bound_bio']] = 0 merge_c.loc[~mask, 'lower_total'] = merge_c.loc[~mask, 'bio_met_min'] * 0.051 merge_c.loc[~mask, 'higher_total'] = merge_c.loc[~mask, 'bio_met_min'] * 0.053 merge_c.loc[~mask, 'lower_total_ng'] = merge_c.loc[~mask, '2019-CON'] * 0.008 merge_c.loc[~mask, 'higher_total_ng'] = merge_c.loc[~mask, '2019-CON'] * 0.022
内容的提问来源于stack exchange,提问作者Pietro Marconi
相关产品推荐
相关产品推荐

