如何迭代pandas数据帧的特定列的行以执行calucation

时间:2018-05-18 04:45:24

标签: pandas loops dataframe

我有一个数据框,有各种仓库的各种产品的库存余额和需求

以下是来自一个仓库的一个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

2 个答案:

答案 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']