You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python pandas实现df1与df2匹配扣减库存WIP生成新数据框

问题解答

技术选型建议

用pandas实现更合适。你的需求属于结构化表格的分组匹配、带业务逻辑的逐行迭代处理场景,pandas对表格数据的分组、合并、自定义迭代处理的支持更贴合需求,numpy更适合纯数值矩阵的批量运算,处理这类带业务规则的拆分行、分类打标的场景会更繁琐。

核心实现思路

核心逻辑是按物料分组,按照交付日期从早到晚的顺序优先抵扣库存,再抵扣在制品,最后剩余部分标记为计划量,具体步骤如下:

  • 预处理:将待交付表df1按Item、Date升序排序,保证先到期的交付需求优先被抵扣;将库存表df2转换为以物料为key的字典,存储每个物料的可用Stock、WIP余额,方便后续扣减更新。
  • 按物料分组迭代:对每个物料单独走抵扣流程:
    1. 初始化当前物料可用的Stock、WIP数值
    2. 遍历该物料的每一条待交付记录,拿到当前需要抵扣的数量curr_qty
    3. 优先扣Stock:如果Stock还有余额,取min(curr_qty, Stock)作为本次Stock抵扣量,生成对应记录;更新剩余Stock和剩余待抵扣量,如果待抵扣量为0则跳过后续步骤,处理下一条记录
    4. 再扣WIP:如果WIP还有余额,取min(剩余待抵扣量, WIP)作为本次WIP抵扣量,生成对应记录;更新剩余WIP和剩余待抵扣量,如果待抵扣量为0则处理下一条记录
    5. 剩余待抵扣量全部标记为Planned,生成对应记录
  • 所有物料的抵扣记录合并后即为最终结果

可运行代码示例

import pandas as pd

# 你的样例数据
data1 = [["Apple", "2021/1/1", 3], ["Apple", "2021/3/1", 2], ["Apple", "2021/7/1", 7], ["Banana", "2023/1/1", 10], ["Banana", "2023/12/1", 5], ["Banana", "2024/1/1", 3], ["Kiwi", "2021/2/1", 2], ["Kiwi", "2021/2/2", 1], ["Kiwi", "2021/2/3", 9], ["Kiwi", "2021/2/3", 20]]
df1 = pd.DataFrame(data1, columns=['Item', 'Date', "Quantity Remaining"])
data2 = [["Apple", 2, 7], ["Banana", 10, 8], ["Kiwi", 10, 5]]
df2 = pd.DataFrame(data2, columns=["Item", "Stock", "WIP"])

# 预处理1:df1按日期排序,保证先到期先抵扣
df1 = df1.sort_values(by=['Item', 'Date']).reset_index(drop=True)
# 预处理2:df2转字典
stock_dict = df2.set_index('Item').to_dict('index')

result = []
# 按物料分组处理
for item, group in df1.groupby('Item'):
    # 拿到当前物料的库存和WIP
    curr_stock = stock_dict[item]['Stock']
    curr_wip = stock_dict[item]['WIP']
    # 遍历该物料的每笔待交付
    for _, row in group.iterrows():
        date = row['Date']
        remain = row['Quantity Remaining']
        # 先扣库存
        if curr_stock > 0 and remain > 0:
            deduct = min(remain, curr_stock)
            result.append([item, date, deduct, 'Stock'])
            curr_stock -= deduct
            remain -= deduct
        # 再扣WIP
        if curr_wip > 0 and remain > 0:
            deduct = min(remain, curr_wip)
            result.append([item, date, deduct, 'WIP'])
            curr_wip -= deduct
            remain -= deduct
        # 剩余标Planned
        if remain > 0:
            result.append([item, date, remain, 'Planned'])

# 转成DataFrame
outcome = pd.DataFrame(result, columns=["Item", "Delivery Date", "Quantity", "Note"])
print(outcome)

注:你提供的预期输出样例里Banana的2023/9/1属于笔误,按照输入数据所有Banana的交付日期只有2023/1/1、2023/12/1、2024/1/1,代码运行结果会保留原始交付日期,符合需求要求。

内容的提问来源于stack exchange,提问作者Illusoma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 15:06:10