匹配DataFrame共同产品编码计算价差时遇ValueError报错求助
解决pandas ValueError: The truth value of a Series is ambiguous问题
错误原因分析
- 你传入自定义函数
range_calc的是整列数据(pandas Series),而非单个产品的价格值。函数中abs_res == 0、z>y这类比较会返回布尔值组成的Series,但if语句需要单个布尔值,因此触发"truth value ambiguous"错误。 - 嵌套循环的逻辑完全错误:每次匹配到产品编码时,直接给
Last_df的整列赋值当前编码,会覆盖之前所有数据;同时函数处理的是整列而非对应产品的价格,根本无法实现按产品计算的需求。
修正方案(高效向量化实现)
步骤1:合并两个DataFrame,对齐共同产品
先通过内连接合并两个DataFrame,只保留双方都有的产品编码,同时关联对应的价格:
import pandas as pd import numpy as np # 假设df1列名:product_ID(产品编码)、full_price(价格);df2列名:product_code(产品编码)、tot_price(价格) merged_df = pd.merge( df1[["product_ID", "full_price"]], df2[["product_code", "tot_price"]], left_on="product_ID", right_on="product_code", how="inner" # 只保留共同产品 )
步骤2:向量化计算价差比例
用np.where实现向量化判断,避免循环和单个值的函数调用,效率更高:
# 计算价格差的绝对值 abs_diff = abs(merged_df["full_price"] - merged_df["tot_price"]) # 按规则计算最终价格比例 merged_df["Market_Price"] = np.where( abs_diff == 0, merged_df["full_price"], # 价格相等时返回原价格 np.where( merged_df["full_price"] > merged_df["tot_price"], (abs_diff / merged_df["full_price"]) * 100, (abs_diff / merged_df["tot_price"]) * 100 ) ) # 生成最终的df3 df3 = merged_df[["product_ID", "Market_Price"]].rename(columns={"product_ID": "Product_number"})
可选方案(自定义函数+行级应用)
如果一定要保留自定义函数的逻辑,可以对合并后的每行数据应用函数:
def range_calc(row): z = row["full_price"] y = row["tot_price"] abs_res = abs(z - y) if abs_res == 0: return z return (abs_res / z) * 100 if z > y else (abs_res / y) * 100 # 合并后按行应用函数 merged_df = pd.merge( df1[["product_ID", "full_price"]], df2[["product_code", "tot_price"]], left_on="product_ID", right_on="product_code", how="inner" ) merged_df["Market_Price"] = merged_df.apply(range_calc, axis=1) df3 = merged_df[["product_ID", "Market_Price"]].rename(columns={"product_ID": "Product_number"})
内容的提问来源于stack exchange,提问作者Mahmoud Wahba
相关产品推荐
相关产品推荐

