【问题标题】:What is the best way to compute a rolling (lag and lead) difference in sales?计算销售额滚动(滞后和领先)差异的最佳方法是什么?
【发布时间】:2019-09-18 09:47:33
【问题描述】:

我希望在我的数据集中添加一两个字段,以表示从上周到本周以及从本周到下周的销售额差异。

我的数据集大约有 450 万行,因此我正在寻找一种有效的方法来执行此操作,目前我正在进行大量迭代和 for 循环,我很确定我会解决这个问题错误道。但是我正在尝试编写可在其他数据集上重用的代码,并且在某些情况下,您可能每周都有空值或销售量没有变化(因此没有记录)

数据集如下所示:

Store  Item  WeekID  WeeklySales
1      1567   34      100.00
2      2765   34      86.00
3      1163   34      200.00
1      1567   35      160.00
.      .
.      . 
.      .

我把每个星期都当成自己的字典,然后把每家商店那一周的销售额放在字典里面。所以我可以使用周作为键,然后在周内访问商店的商品销售字典。

weekly_sales_dict = {}
for i in df['WeekID'].unique():
    store_items_dict = {}
    subset = df[df['WeekID'] == i]
    subset = subset.groupby(['Store', 'Item']).agg({'WeeklySales':'sum'}).reset_index()
    for j in subset['Store'].unique():
        storeset = subset[subset['Store'] == j]
        store_items_dict.update({str(j): storeset})
    weekly_sales_dict.update({ str(i) : store_items_dict})

然后我在weekly_sales_dict 中的每个星期进行迭代,并将其中的每个商店/商品与其后一周进行比较(我计划下周也这样做)。我创建的“lag_list”可以按周、商店和项目进行索引,因此我打算遍历并将值作为新的滞后列添加到我的 df 中,但我觉得我想太多了。

count = 0 
key_list = list(df['WeekID'].unique())
lag_list = []
for k,v in weekly_sales_dict.items():
    if count != 0 and count != len(df['WeekID'].unique())-1:
        prev_wk = weekly_sales_dict[str(key_list[(count - 1)])]
        current_wk = weekly_sales_dict[str(key_list[count])
        for i in df['Store'].unique():
            prev_df = prev_wk[str(i)]
            current_df = current_wk[str(i)]
            for j in df['Item'].unique():
                print('in j')
                if j in list(current_df['Item'].unique()) and j in list(prev_df['Item'].unique()):
                    item_lag = current_df[current_df['Item'] == int(j)]['WeeklySales'].values - prev_df[prev_df['Item'] == int(j)]['WeeklySales'].values
                    df[df['Item'] == j][df['Store'] == i ][df['WeekID'] == key_list[count]]['lag'] = item_lag[0]
                    lag_list.append((str(i),str(j),item_lag[0]))
                elif j in list(current_df['Item'].unique()):
                    item_lag = current_df[current_df['Item'] == int(j)]['WeeklySales'].values
                    lag_list.append((str(i),str(j),item_lag[0]))
                else:
                    pass
        count += 1
    else:            
        count += 1

【问题讨论】:

  • 你看过pd.DataFrame.rolling()吗?
  • 我看过它,但这些示例似乎侧重于确定时期的日期,因为我使用的是周 ID,我认为我可能不得不走不同的路线
  • 如果到那时还没有答案,我可以在大约 4 小时内解决一个问题
  • 我忘了!你还卡着吗?
  • 不用担心!我在这方面没有取得任何进展......我今天打算尝试 pd.rolling() 但这些例子对我来说不太有意义。

标签: python python-3.x performance iteration rolling-computation


【解决方案1】:

使用pd.diff() 解决了问题。我按周对所有行进行了排序,然后通过对商店、项目和周进行分组来创建具有多索引的子集。最后,我使用了 pd.diff() 的周期为 1,最终得到了从本周到前一周的销售差异。

df = df.sort_values(by = 'WeekID')

subset = df.groupby(['Store', 'Items', 'WeekID']).agg({''WeeklySales'':'sum'})
subset['lag']  = subset[['WeeklySales']].diff(1)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-04
    • 2020-11-13
    • 2020-09-26
    • 1970-01-01
    • 2018-09-21
    • 1970-01-01
    相关资源
    最近更新 更多