求助:用Python Pandas开发月度库存PSI模拟工具的正确编码
月度库存模拟工具(PSI)开发问题解决
问题描述
需要基于Python Pandas开发月度库存模拟工具,用于估算月末库存数量,核心公式为:
上月月末库存 + 当月入库量(IN) - 当月出库量(OUT) = 当月月末库存
尝试用for循环实现时出现错误,原代码如下:
df1 = pd.DataFrame({'Month':['Jan','Feb','Mar','Apr','May'],'IN ':[120,80,60,80,100]}) df2 = pd.DataFrame({'Month':['Jan','Feb','Mar','Apr','May'],'OUT ':[100,50,60,70,120]}) merged_df = pd.merge(df1, df2, on='Month') merged_df['Inventory']=0 for idx, row in merged_df.iterrows(): merged_df['Inventory'] = merged_df.loc[idx,'IN']+ merged_df.loc[idx,'IN']-merged_df.loc[idx,'OUT'] merged_df
原代码问题分析
- 列名匹配错误:
df1和df2中的列名是'IN '和'OUT '(末尾带空格),但代码中用'IN'和'OUT'会导致找不到列 - 循环逻辑错误:每次赋值都覆盖整个
Inventory列,且计算式错误(重复加了两次IN,未用上月库存值) - 效率低下:
iterrows()在数据量大时性能差,不符合Pandas的向量化操作理念
正确实现方式
方式1:修复循环逻辑(适合理解过程)
先修正列名,再通过循环逐行计算并更新上月库存:
import pandas as pd # 修正列名,去掉末尾空格 df1 = pd.DataFrame({'Month':['Jan','Feb','Mar','Apr','May'],'IN':[120,80,60,80,100]}) df2 = pd.DataFrame({'Month':['Jan','Feb','Mar','Apr','May'],'OUT':[100,50,60,70,120]}) merged_df = pd.merge(df1, df2, on='Month') merged_df['Inventory'] = 0 # 初始化期初库存(假设为0,可根据实际修改) prev_inventory = 0 for idx, row in merged_df.iterrows(): current_inventory = prev_inventory + row['IN'] - row['OUT'] merged_df.loc[idx, 'Inventory'] = current_inventory prev_inventory = current_inventory # 更新上月库存为当前月末值 print(merged_df)
方式2:向量化操作(推荐,高效简洁)
利用Pandas的cumsum()函数实现累加,无需循环:
import pandas as pd df1 = pd.DataFrame({'Month':['Jan','Feb','Mar','Apr','May'],'IN':[120,80,60,80,100]}) df2 = pd.DataFrame({'Month':['Jan','Feb','Mar','Apr','May'],'OUT':[100,50,60,70,120]}) merged_df = pd.merge(df1, df2, on='Month') # 计算每月库存变化量 merged_df['Inventory_Change'] = merged_df['IN'] - merged_df['OUT'] # 累加变化量得到月末库存(期初库存设为0,可自行调整) merged_df['Inventory'] = merged_df['Inventory_Change'].cumsum() # 若有初始库存(比如期初为50),修改为: # initial_inventory = 50 # merged_df['Inventory'] = initial_inventory + merged_df['Inventory_Change'].cumsum() print(merged_df)
两种方式运行后都会得到正确的月末库存结果:
| Month | IN | OUT | Inventory |
|---|---|---|---|
| Jan | 120 | 100 | 20 |
| Feb | 80 | 50 | 50 |
| Mar | 60 | 60 | 50 |
| Apr | 80 | 70 | 60 |
| May | 100 | 120 | 40 |
内容的提问来源于stack exchange,提问作者Sattai
相关产品推荐
相关产品推荐

