Python Pandas计算门店SKU每日库存:期初表+交易表滚动求和问题
库存滚动计算问题排查与实现方案
原代码问题分析
new_frame每次循环都被重新初始化:你在每一组门店+SKU的循环里都重新创建了空的new_frame,之前循环生成的所有结果都会被直接覆盖,最终仅返回最后一次循环的计算结果,这是你只拿到少量结果的核心原因。- 函数参数未生效:你定义函数时声明了
loc和sk两个入参,但函数内部循环用的是全局变量locations和skus,参数完全没有被用到。 - 缺失组合的赋值逻辑错误:当
first_day中不存在对应门店+SKU组合时,你给SKU赋值用的是skus[0],会把所有缺失组合的SKU都固定成第一个SKU,完全不符合预期。 - 效率极低:嵌套循环+逐行赋值的写法在数据量稍大时会非常慢,完全没有利用pandas的向量化计算优势。
正确实现方案
直接用pandas分组累计求和的逻辑实现,无需嵌套循环,代码简洁高效:
import pandas as pd import numpy as np # 原有数据读取和预处理逻辑保留 first_day = pd.read_csv(r"C:\Users\Inventory_First_day.csv") transactions = pd.read_csv(r"C:\Users\Transactions.csv") transactions['Transaction Type'] = transactions['Transaction Type'].replace({'SALE': -1, 'OUT': -1, 'IN': 1}) transactions['total'] = transactions['Transaction Type'] * transactions['Quantity'] # ---------------------- 核心计算逻辑 ---------------------- # 1. 预处理期初表,只保留需要的字段 first_day_preprocess = first_day.rename(columns={'Inventory': 'initial_inventory'})[['Stock Location Name', 'SKU', 'initial_inventory']] # 2. 交易表关联期初库存,拿到每个门店+SKU的初始值,不存在的组合期初库存填0 trans_with_initial = pd.merge( transactions, first_day_preprocess, on=['Stock Location Name', 'SKU'], how='left' ) trans_with_initial['initial_inventory'] = trans_with_initial['initial_inventory'].fillna(0) # 3. 按门店+SKU分组,先按日期排序,再对交易净额做累计求和,加期初库存得到每日余额 trans_with_initial = trans_with_initial.sort_values(by=['Stock Location Name', 'SKU', 'Date']) trans_with_initial['cum_total'] = trans_with_initial.groupby(['Stock Location Name', 'SKU'])['total'].cumsum() trans_with_initial['库存数量'] = trans_with_initial['initial_inventory'] + trans_with_initial['cum_total'] # 4. 输出符合要求的结果 result = trans_with_initial.rename(columns={ 'Stock Location Name': '门店', 'Date': '日期' })[['门店', 'SKU', '日期', '库存数量']].reset_index(drop=True)
如果需要包含没有交易记录的门店+SKU的库存数据,把merge的how参数改成outer,再对应补全日期字段即可。
内容的提问来源于stack exchange,提问作者paul
相关产品推荐
相关产品推荐

