我有一个数据框,有各种仓库的各种产品的库存余额和需求
以下是来自一个仓库的一个SKU的3天数据
ActivityDate DepotName Company SKU Balance Demand
1/10/2017 Depot1 A SKU1 10 1
2/10/2017 Depot1 A SKU1 9 1
3/10/2017 Depot1 A SKU1 8 1
4/10/2017 Depot1 A SKU1 7 1
我想计算每天的安全库存,公式是
10月1日SafetyStock =需求(1stOct + 2ndOct + 3rdOct)/余额(10月1日)
我的第一个问题是
如何计算每天的安全库存?
我正在寻找的答案是
ActivityDate DepotName Company SKU Balance Demand SS
1/10/2017 Depot1 A SKU1 10 1 0.30
2/10/2017 Depot1 A SKU1 9 1 0.33
3/10/2017 Depot1 A SKU1 8 1
4/10/2017 Depot1 A SKU1 7 1
较大的数据集具有各种SKU和各种仓库的所有需求和库存余额,看起来像
Date DepotName Company SKU Stock Sales
1/10/2017 Depot1 A SKU1 10 1
1/10/2017 Depot1 A SKU2 20 1
1/10/2017 Depot1 A SKU3 30 1
2/10/2017 Depot1 A SKU1 9 1
2/10/2017 Depot1 A SKU2 19 1
2/10/2017 Depot1 A SKU3 29 1
3/10/2017 Depot1 A SKU1 8 1
3/10/2017 Depot1 A SKU2 18 1
3/10/2017 Depot1 A SKU3 28 1
在这种情况下,我如何计算每天每个SKU的安全库存。非常感谢您的帮助
P.S:为了理解,我还没有包括其他仓库和其他公司的数据。我希望我可以使用此答案在公司和仓库级别实施。
编辑1:
只是为了向您展示我的实际数据,它看起来像
Date DepotName Company SKU Stock Sales
1/10/2017 Depot1 A SKU1 10 4
1/10/2017 Depot1 A SKU2 20 5
1/10/2017 Depot1 A SKU3 30 6
1/10/2017 Depot2 B SKU4 10 4
1/10/2017 Depot2 B SKU5 20 5
1/10/2017 Depot2 B SKU6 30 6
1/10/2017 Depot3 C SKU7 10 4
1/10/2017 Depot3 C SKU8 20 5
1/10/2017 Depot3 C SKU9 30 6
2/10/2017 Depot1 A SKU1 9 1
2/10/2017 Depot1 A SKU2 19 1
2/10/2017 Depot1 A SKU3 29 1
2/10/2017 Depot2 B SKU4 10 4
2/10/2017 Depot2 B SKU5 20 5
2/10/2017 Depot2 B SKU6 30 6
2/10/2017 Depot3 C SKU7 10 4
2/10/2017 Depot3 C SKU8 20 5
2/10/2017 Depot3 C SKU9 30 6
3/10/2017 Depot1 A SKU1 8 1
3/10/2017 Depot1 A SKU2 18 1
3/10/2017 Depot1 A SKU3 28 1
3/10/2017 Depot2 B SKU4 10 4
3/10/2017 Depot2 B SKU5 20 5
3/10/2017 Depot2 B SKU6 30 6
3/10/2017 Depot3 C SKU7 10 4
3/10/2017 Depot3 C SKU8 20 5
3/10/2017 Depot3 C SKU9 30 6
Depots,Company和SKU有很多类别
基本上,我需要一个代码来过滤每个仓库,每个公司每个SKU,然后执行安全库存等等,直到涵盖所有仓库,公司和SKU
答案 0 :(得分:2)
回答第一个问题,您可以使用pd.Series.rolling()
。
从
开始z = io.StringIO("""\
ActivityDate DepotName Company SKU Balance Demand
1/10/2017 Depot1 A SKU1 10 1
2/10/2017 Depot1 A SKU1 9 1
3/10/2017 Depot1 A SKU1 8 1
4/10/2017 Depot1 A SKU1 7 1""")
df = pd.read_table(z, delim_whitespace=True)
你可以做到
df.Demand[::-1].rolling(3).sum()[::-1]/df.Balance
产生
0 0.300000
1 0.333333
2 NaN
3 NaN
dtype: float64
对于完整的df
,您可以在应用rolling
金额之前使用groupby
。
所以,从
开始z2 = io.StringIO("""\
Date DepotName Company SKU Stock Sales
1/10/2017 Depot1 A SKU1 10 1
1/10/2017 Depot1 A SKU2 20 1
1/10/2017 Depot1 A SKU3 30 1
2/10/2017 Depot1 A SKU1 9 1
2/10/2017 Depot1 A SKU2 19 1
2/10/2017 Depot1 A SKU3 29 1
3/10/2017 Depot1 A SKU1 8 1
3/10/2017 Depot1 A SKU2 18 1
3/10/2017 Depot1 A SKU3 28 1""")
df = pd.read_table(z2, delim_whitespace=True)
您可以先获得销售的滚动金额,即
df.groupby("SKU").Sales.rolling(3).sum()
和您的股票系列的第一个值(即您的分母)
df.groupby("SKU").Stock.apply(list).apply(lambda k: k[0])
然后,只需将这些值除以获得
(df.groupby("SKU").Sales.rolling(3).sum()/df.groupby("SKU").Stock.apply(list).apply(lambda k: k[0]))[::-1]
SKU
SKU3 8 0.10
5 NaN
2 NaN
SKU2 7 0.15
4 NaN
1 NaN
SKU1 6 0.30
3 NaN
0 NaN
答案 1 :(得分:0)
我设法找到了这个问题的解决方法。
首先,我按日期对记录进行了分类
df.sort_values('Date',inplace=True)
然后我使用了groubyby和rolling的组合。
按分类属性进行分组,并通过汇总Sales来滚动日期。
我已经扭转了整个事情来做前瞻性的总和。
df1 = (df.iloc[::-1]
.groupby(['DepotName','Company','SKU'],sort=False)
.rolling(7, on='Date',min_periods=0).Sales
.sum()
.iloc[::-1])
然后我合并了两个数据帧
df = df.merge(df1, on=['Date','DepotName','Company','SKU'], how='left')
然后我做了安全库存计算。
ss3['SafetyStock']=ss3['7DaysSum']/ss3['Stock']