如何在Pandas数据框中遍历列,确定Price值所在的区间对?
解决方案
错误原因分析
你遇到的ValueError: The truth value of a Series is ambiguous,是因为df1["Price"].between(...)返回的是整个Series的布尔结果,而if语句需要单个布尔值,Pandas无法判断你要的是全满足还是任意满足,因此报错。另外手动循环itertuples效率低,不符合Pandas的向量化操作思路。
实现步骤与代码
我们可以通过提取P/Q列、逐行匹配区间的方式实现需求,同时处理P列可能的降序情况:
- 构造测试数据(对应你的输入):
import pandas as pd data = { 'Quantity': [1.1, 2.2, 3.3], 'Price': [100.1, 900.2, 300.3], 'data1': ['A', 'B', 'C'], 'data2': ['D', 'E', 'F'], 'Q1': [4.4, 5.5, 6.6], 'P1': [700.7, 800.8, 900.9], 'Q2': [4.4, 5.5, 6.6], 'P2': [100.1, 810.1, 120.2], 'Q3': [13.3, 14.4, 15.5], 'P3': [1300.3, 1400.4, 1500.5] } df = pd.DataFrame(data)
- 提取并排序P/Q列:
确保按数字后缀(1、2、3...)排序,避免列顺序混乱:
# 获取所有P列和Q列,按数字后缀排序 p_cols = sorted([col for col in df.columns if col.startswith('P')], key=lambda x: int(x[1:])) q_cols = sorted([col for col in df.columns if col.startswith('Q')], key=lambda x: int(x[1:]))
- 定义区间匹配函数:
逐行检查Price落在哪个P区间,返回对应的Q/P组合:
def find_matching_interval(row): price = row['Price'] # 遍历所有连续的P列对 for i in range(len(p_cols)-1): p_left = row[p_cols[i]] p_right = row[p_cols[i+1]] # 兼容P列升序/降序的情况,判断Price是否在区间内 if min(p_left, p_right) <= price <= max(p_left, p_right): # 提取对应的Q列值,组合成结果字符串 q_left_val = row[q_cols[i]] q_right_val = row[q_cols[i+1]] return f"{q_left_val},{p_left}", f"{q_right_val},{p_right}" # 若未找到匹配区间,返回空值(可根据需求调整) return None, None
- 应用函数生成结果列:
# 逐行应用函数,生成output1和output2列 df[['output1', 'output2']] = df.apply(find_matching_interval, axis=1, result_type='expand') # 查看最终结果 print(df)
运行结果
输出将完全符合你的预期:
Quantity Price data1 data2 Q1 P1 Q2 P2 Q3 P3 output1 output2 0 1.1 100.1 A D 4.4 700.7 4.4 100.1 13.3 1300.3 4.4,700.7 4.4,100.1 1 2.2 900.2 B E 5.5 800.8 5.5 810.1 14.4 1400.4 5.5,810.1 14.4,1400.4 2 3.3 300.3 C F 6.6 900.9 6.6 120.2 15.5 1500.5 6.6,900.9 6.6,120.2
内容的提问来源于stack exchange,提问作者Twinkle
相关产品推荐
相关产品推荐

