如何在不使用循环或对Pandas中的groupby组进行迭代的情况下,将可滚动窗口应用滚动功能?

时间:2018-06-20 22:03:11

标签: python pandas numpy

这个问题实际上是该previous one的“附带利益”

但是这次,假设您有一个“ DataFrame”但更大了

      DATE  ITEM   STORE   LT  SALES
2018-06-06     A    L001    4      3
2018-06-06     A    L002    2      1
2018-06-06     A    L003    3      3
2018-06-06     B    L001    4      1
2018-06-06     B    L002    2      0

我添加了代表“交货时间”的“ LT”列,并切换了“销售”的库存。这只是“ DataFrame”的头。您可以使用以下代码复制相同的内容:

import pandas as pd
import numpy as np
import itertools as it

lojas = ['L001', 'L002', 'L003']
itens = list("ABC")
lead_times = {'L001':4,'L002':2,'L003':3}
dr = pd.date_range(start='2018-06-06', end='2018-06-12')

df = pd.DataFrame(data=list(it.product(dr, itens, lojas)), columns=['DATE', 'ITEM', 'STORE'])
df['LT'] = df.STORE.map(lead_times)
df['SALES'] = np.random.RandomState(seed=101).randint(0,5, size=len(df.ITEM))

如果您阅读了该线程,则会看到用户@coldspeed提供了以下答案来计算两天之间的位置库存差异:

v = df.groupby(['ITEM', 'STORE'], sort=False).STOCK.diff()
df['DELTA'] = np.where(np.isnan(v), 0, v)

现在想象一下,我们现在想要的是在每个STORE中计算销售的滚动总和(正向),但是window参数取决于LT列。产生结果如下(我将头部和尾部附加在一起,以便您可以看到两个示例):

      DATE  ITEM    STORE   LT  SALES   ACC_SALES
2018-06-06     A     L001    4      3         7.0
2018-06-07     A     L001    4      0        11.0
2018-06-08     A     L001    4      3        11.0
2018-06-09     A     L001    4      0         NaN
2018-06-10     A     L001    4      4         NaN
2018-06-11     A     L001    4      4         NaN
2018-06-12     A     L001    4      3         NaN
...
2018-06-06     C     L003    3      4         8.0
2018-06-07     C     L003    3      3         7.0
2018-06-08     C     L003    3      3         8.0
2018-06-09     C     L003    3      2         6.0
2018-06-10     C     L003    3      2         NaN
2018-06-11     C     L003    3      4         NaN
2018-06-12     C     L003    3      0         NaN

[编辑] 有我用来计算“ ACC_SALES ”的代码:

grouped_df = df.groupby(['ITEM','STORE'])
auxlist = []

for (name, group) in grouped_df:
    aux = group.copy()
    aux.sort_values('DATE', inplace=True)
    aux.reset_index(drop=True, inplace=True)
    win = lead_times[aux.STORE.iloc[0]]
    aux['ACC_SALES'] = aux.SALES.rolling(window=win, min_periods=1).sum().shift(-1*win)
    auxlist.append(aux)

df = pd.concat(auxdf)

是否存在一种快速,矢量化的“ numpythonic”方式来获得此结果,而无需遍历各个组?

0 个答案:

没有答案