如何向量化实现供需DataFrame按优先级扣减匹配,提升大订单量效率
向量化优化供需匹配方案
你的核心问题是用apply逐行处理导致万级订单效率低下,而且直接修改全局supply表的操作在pandas里是性能杀手。下面是完全向量化的实现思路,利用分组和累计求和替代循环,能把效率提升几个数量级:
实现思路
- 分组排序:先把需求表按
Item-Location分组,每组内按Priority升序(默认数字越小优先级越高)排序,保证高优先级订单先被处理。 - 累计需求计算:对每组的
Demand Quantity做累计求和,得到每个订单对应的累计需求总量。 - 关联供应数据:将供应表的
Supply字段关联到对应的Item-Location组中。 - 计算满足量:
- 若当前累计需求 ≤ 供应总量,该订单需求可被完全满足;
- 若当前累计需求 > 供应总量,分两种情况:
- 前一个累计需求 ≤ 供应总量:满足量 = 供应总量 - 前一个累计需求;
- 前一个累计需求也 > 供应总量:满足量 = 0;
- 更新剩余供应:每组剩余供应 = 供应总量 - 该组总满足量(若总满足量超过供应则剩余0)。
完整代码
import pandas as pd def match_demand_supply(demands, supply): # 1. 预处理需求表:按Item-Location分组,每组内按Priority排序 demands_sorted = demands.sort_values(by=["Item", "Location", "Priority"], ignore_index=True) # 2. 计算每组内的累计需求及前一个累计需求 demands_sorted["Cumulative Demand"] = demands_sorted.groupby(["Item", "Location"])["Demand Quantity"].cumsum() demands_sorted["Prev Cumulative Demand"] = demands_sorted.groupby(["Item", "Location"])["Cumulative Demand"].shift(1, fill_value=0) # 3. 关联供应数据,处理无对应供应的情况 demands_merged = demands_sorted.merge( supply[["Item", "Location", "Supply"]], on=["Item", "Location"], how="left" ) demands_merged["Supply"] = demands_merged["Supply"].fillna(0) # 4. 计算每个订单的满足量 mask_full = demands_merged["Cumulative Demand"] <= demands_merged["Supply"] mask_partial = (demands_merged["Prev Cumulative Demand"] <= demands_merged["Supply"]) & (demands_merged["Cumulative Demand"] > demands_merged["Supply"]) mask_none = demands_merged["Prev Cumulative Demand"] > demands_merged["Supply"] demands_merged["Fulfilled Quantity"] = 0 demands_merged.loc[mask_full, "Fulfilled Quantity"] = demands_merged.loc[mask_full, "Demand Quantity"] demands_merged.loc[mask_partial, "Fulfilled Quantity"] = demands_merged.loc[mask_partial, "Supply"] - demands_merged.loc[mask_partial, "Prev Cumulative Demand"] # 5. 更新供应表的剩余数量 supply_remaining = demands_merged.groupby(["Item", "Location"]).agg( Total_Fulfilled=("Fulfilled Quantity", "sum"), Original_Supply=("Supply", "first") ).reset_index() supply_remaining["Remaining Supply"] = (supply_remaining["Original_Supply"] - supply_remaining["Total_Fulfilled"]).clip(lower=0) supply_updated = supply.merge( supply_remaining[["Item", "Location", "Remaining Supply"]], on=["Item", "Location"], how="left" ) supply_updated["Supply"] = supply_updated["Remaining Supply"].fillna(supply_updated["Supply"]) supply_updated = supply_updated.drop(columns=["Remaining Supply"]) # 返回处理后的需求表和更新后的供应表 return demands_merged.drop(columns=["Cumulative Demand", "Prev Cumulative Demand"]), supply_updated
关键优化点
- 完全摒弃
apply循环,全部用pandas向量化运算,万级数据处理速度从秒级降至毫秒级; - 不再直接修改全局
supply表,通过分组聚合计算剩余供应,保证数据一致性和线程安全; - 处理了无对应供应的边缘情况,避免空值报错。
使用示例
# 示例需求表 demands = pd.DataFrame({ "Item": ["A", "A", "B", "A"], "Location": ["NY", "NY", "LA", "NY"], "Demand Quantity": [3, 5, 4, 2], "Priority": [2, 1, 1, 3] }) # 示例供应表 supply = pd.DataFrame({ "Item": ["A", "B"], "Location": ["NY", "LA"], "Supply": [7, 5] }) fulfilled_demands, updated_supply = match_demand_supply(demands, supply) print(fulfilled_demands) print(updated_supply)
内容的提问来源于stack exchange,提问作者Siddharamesh
相关产品推荐
相关产品推荐

