如何使用for循环操作pandas列增减,实现按优先级分配待发货库存
原有代码问题分析
- 遍历逻辑错误:
groupby操作返回的是「(分组键, 分组数据)」的元组迭代器,不能直接和数值0比较 - 赋值范围错误:所有列更新都是全表操作,没有针对组内周库存最低的行做修改,也没有区分不同分组的剩余待发货量
- 累加逻辑错误:
df['SEND_PKGS'] = +1这类写法是把整列值覆盖为1,不是对目标行做累加操作
可直接运行的实现方案
首先初始化数据和新增列:
import pandas as pd # 构造原始数据集 df = pd.DataFrame([ ['SUP1', 'P1', 'STR1', 50, 5, 18], ['SUP1', 'P1', 'STR2', 6, 7, 18], ['SUP1', 'P1', 'STR3', 74, 4, 18], ['SUP2', 'P4', 'STR1', 35, 3, 500], ['SUP2', 'P4', 'STR2', 5, 4, 500], ['SUP2', 'P4', 'STR3', 54, 7, 500], ], columns=['SUPPLIER', 'PRODUCTID', 'STOREID', 'BALANCE', 'AVG_SALES', 'TO_SHIP']) # 初始化目标字段 df['SEND_PKGS'] = 0 df['Wk_Bal'] = df['BALANCE'] / df['AVG_SALES']
然后执行循环分配逻辑,完全匹配需求:
# 只要还有待发货的分组就继续循环 while df['TO_SHIP'].gt(0).any(): # 1. 筛选还有待发货量的行,按供应商+产品分组找周库存最低的行索引 valid_rows = df[df['TO_SHIP'] > 0] min_wk_idx = valid_rows.groupby(['SUPPLIER', 'PRODUCTID'])['Wk_Bal'].idxmin() # 2. 给周库存最低的行累加发货量、库存 df.loc[min_wk_idx, 'SEND_PKGS'] += 1 df.loc[min_wk_idx, 'BALANCE'] += 1 # 3. 对应分组的待发货量减1 for (supplier, product), _ in min_wk_idx.items(): group_mask = (df['SUPPLIER'] == supplier) & (df['PRODUCTID'] == product) df.loc[group_mask, 'TO_SHIP'] -= 1 # 4. 重新计算全表周库存 df['Wk_Bal'] = df['BALANCE'] / df['AVG_SALES'] # 可选:保留两位小数格式化Wk_Bal方便查看 df['Wk_Bal'] = df['Wk_Bal'].round(2)
逻辑说明
- 如果遇到组内多门店
Wk_Bal并列最低的情况,上述代码会默认选择排序在前的门店,如需自定义优先级可以在取idxmin前给分组内数据加排序规则即可 - 若待发货总量较大(比如单组超过10000),可以优化为批量分配不用逐次加1,普通业务场景下上述代码性能足够使用
内容的提问来源于stack exchange,提问作者its.kcl
相关产品推荐
相关产品推荐

