pandas中应用完美和算法实现多列值匹配的高效方法
解决方案
核心实现思路
你只需要先过滤匹配Rate的无效数据,再修改完美和函数返回行索引而非数值,最后映射回原始DataFrame即可,具体步骤如下:
- 先从df中筛选出Rate和df2中目标Rate一致的行,大幅减少后续计算量
- 提取上述筛选结果的Price列表与对应原始索引列表,作为完美和算法的输入
- 调整完美和函数逻辑,返回符合求和条件的索引子集,而非Price数值子集
- 用返回的索引子集从原始df中提取对应的行组合即可
完整可运行代码
import pandas as pd # 示例数据构造 df = pd.DataFrame({ 'Price': [100, 50, 50, 150], 'Rate': [10, 10, 14, 10] }) df2 = pd.DataFrame({ 'Price': [300], 'Rate': [10] }) # 改造后的完美和函数,返回符合条件的索引子集 def sumSubsets(price_list, n, target): res = [] def backtrack(index, current_sum, path): if current_sum == target: res.append(path.copy()) return if index >= n or current_sum > target: return # 选当前元素 path.append(index) backtrack(index + 1, current_sum + price_list[index], path) path.pop() # 不选当前元素,跳过重复值优化(可选,避免重复子集) while index + 1 < n and price_list[index] == price_list[index+1]: index += 1 backtrack(index + 1, current_sum, path) backtrack(0, 0, []) return res # 处理逻辑 target_rate = df2.iloc[0]['Rate'] target_price = df2.iloc[0]['Price'] # 第一步:过滤Rate匹配的行 filtered_df = df[df['Rate'] == target_rate].reset_index() filtered_prices = filtered_df['Price'].tolist() original_indices = filtered_df['index'].tolist() # 第二步:找符合求和条件的索引子集 subset_indices_in_filtered = sumSubsets(filtered_prices, len(filtered_prices), target_price) # 第三步:映射回原始df的行 result_combinations = [] for subset in subset_indices_in_filtered: original_subset_indices = [original_indices[i] for i in subset] result_combinations.append(df.loc[original_subset_indices]) # 打印结果示例 for i, comb in enumerate(result_combinations): print(f"符合条件的组合{i+1}:") print(comb) print("-"*20)
输出示例
运行上述代码后会输出你需要的组合:
符合条件的组合1: Price Rate 0 100 10 1 50 10 3 150 10 --------------------
效率优化建议
- 如果df2有多条不同Rate+Price的匹配规则,可以按Rate分组处理,避免交叉计算
- 数据量较大时,可以预先过滤掉filtered_df中Price大于target_price的行,减少回溯计算量
- 所有元素都是正整数的场景下,可以改用动态规划版本的完美和实现,进一步提升运行速度
内容的提问来源于stack exchange,提问作者sudeah
相关产品推荐
相关产品推荐

