基于指定参数在Pandas中筛选最优结果
解决Pandas中基于需求匹配最优采购条目的问题
这是个很常见的采购场景优化需求,我来一步步带你搞定它:我们要根据df1的订单需求,在df2里按价格从低到高挑选对应symbol和年份的供货条目,凑够需求数量,同时不超过每个供货条目的可供应量。
第一步:先明确示例数据结构
先模拟两个符合你需求的DataFrame,方便后续演示:
import pandas as pd # df1:订单需求表(symbol、年份、需要采购的总量) df1 = pd.DataFrame({ 'symbol': ['X', 'Y'], 'year': [2024, 2024], 'required_qty': [125000, 80000] }) # df2:供货信息表(symbol、年份、价格、可供应数量) df2 = pd.DataFrame({ 'symbol': ['X', 'X', 'Y', 'Y'], 'year': [2024, 2024, 2024, 2024], 'price': [10, 12, 15, 18], 'available_qty': [50000, 100000, 60000, 50000] })
第二步:合并+排序,锁定候选供货条目
首先把两个表按symbol和year关联,只保留匹配的条目,然后对每个(symbol, year)组按价格升序排序,这样优先选最便宜的货源:
# 合并两个表,关联条件是symbol和year匹配 merged = pd.merge(df1, df2, on=['symbol', 'year'], how='inner') # 按symbol、year分组,每组内按price从小到大排序 merged_sorted = merged.sort_values(by=['symbol', 'year', 'price'])
第三步:计算每个条目实际采购量
接下来要计算每个供货条目需要拿多少:要么全拿它的可供应量,要么拿剩下还需要的量,直到满足需求。这里用累计求和来判断:
# 按symbol、year分组,计算累计可供应数量 merged_sorted['cumulative_available'] = merged_sorted.groupby(['symbol', 'year'])['available_qty'].cumsum() # 计算还需要的数量(需求总量 - 之前累计已拿的数量) merged_sorted['remaining_needed'] = merged_sorted.groupby(['symbol', 'year'])['required_qty'].transform(lambda x: x - merged_sorted['cumulative_available'].shift(fill_value=0)) # 确定实际采购量:取剩余需要量和可供应量的较小值,不能为负数 merged_sorted['purchase_qty'] = merged_sorted[['remaining_needed', 'available_qty']].min(axis=1) merged_sorted['purchase_qty'] = merged_sorted['purchase_qty'].clip(lower=0)
第四步:生成最终的采购条目列表
最后过滤掉采购量为0的条目,整理成你需要的结果:
# 过滤有效采购条目 final_result = merged_sorted[merged_sorted['purchase_qty'] > 0][['symbol', 'year', 'price', 'available_qty', 'purchase_qty']] # 如果需要生成symbol的列表(按实际采购条目输出) symbol_list = final_result['symbol'].tolist() # 如果需要按采购量重复symbol(比如X对应50000和75000的采购量,拆分显示),可以这样: # symbol_list_expanded = [] # for idx, row in final_result.iterrows(): # # 这里按每1000单位对应一个symbol,可根据需求调整粒度 # symbol_list_expanded.extend([row['symbol']] * (row['purchase_qty'] // 1000))
验证结果
比如你提到的X订单,需求125000:
- 第一个X条目价格10,可供应50000,全拿后还剩75000需求
- 第二个X条目价格12,可供应100000,拿75000就刚好满足需求
最终结果里这两个条目都会保留,完全符合你的预期。
内容的提问来源于stack exchange,提问作者dz333
相关产品推荐
相关产品推荐

