Python:缺少行的多个ID的累积总和

时间:2018-12-20 21:23:42

标签: python pandas cumulative-sum

我有一个大型数据集,其中包含104个唯一的日期和20万个SKU。对于这个解释,我使用3个SKU和4个日期。

数据如下

 Date      SKU        Demand      Supply
 20160501   1            10          10
 20160508   1            35          20
 20160501   2            20          15
 20160508   2            15          20
 20160522   2            5           0
 20160522   3            55          45

仅在需求或供应不为零的情况下填充行。 我要计算累积的供需,同时通过在缺失的日期中添加0,使所有ID的日期范围保持连续。

我的输出将是这样

Date       SKU        Demand      Supply    Cum_Demand    Cum_Supply
20160501     1         10         10         10            10
20160508     1         35         20         45            30
20160515     1         0          0          45            30
20160522     1         0          0          45            30
20160501     2         20         15         20            15
20160508     2         15         20         35            35
20160515     2         0          0          35            35
20160522     2         5          0          40            35
20160501     3         0          0          0             0
20160508     3         0          0          0             0
20160515     3         0          0          0             0
20160522     3         55         45         55            45

数据框的代码

data = pd.DataFrame({'Date':[20160501,20160508,20160501,20160508,20160522,20160522],
                 'SKU':[1,1,2,2,2,3],
                 'Demand':[10,35,20,15,5,55],
                 'Supply':[10,20,15,20,0,45]}
                ,columns=['Date', 'SKU', 'Demand', 'Supply'])

2 个答案:

答案 0 :(得分:1)

需要先reindex,然后groupby + cumsum,然后concatenate才能返回:

import pandas as pd

idx = pd.MultiIndex.from_product([[20160501,20160508,20160515,20160522], 
                                  data.SKU.unique()], names=['Date', 'SKU'])
#If have all unique dates needed in column then: 
#pd.MultiIndex.from_product([np.unique(data.Date), data.SKU.unique()])

data2 = data.set_index(['Date', 'SKU']).reindex(idx).fillna(0)
data2 = pd.concat([data2, data2.groupby(level=1).cumsum().add_prefix('Cum_')], 1).sort_index(level=1).reset_index()

输出data2

        Date  SKU  Demand  Supply  Cum_Demand  Cum_Supply
0   20160501    1    10.0    10.0        10.0        10.0
1   20160508    1    35.0    20.0        45.0        30.0
2   20160515    1     0.0     0.0        45.0        30.0
3   20160522    1     0.0     0.0        45.0        30.0
4   20160501    2    20.0    15.0        20.0        15.0
5   20160508    2    15.0    20.0        35.0        35.0
6   20160515    2     0.0     0.0        35.0        35.0
7   20160522    2     5.0     0.0        40.0        35.0
8   20160501    3     0.0     0.0         0.0         0.0
9   20160508    3     0.0     0.0         0.0         0.0
10  20160515    3     0.0     0.0         0.0         0.0
11  20160522    3    55.0    45.0        55.0        45.0

您需要注意您的约会日期。在这种情况下,我明确列出了顺序,因此较早的日期首先出现。如果它们是数字,则可以使用np.unique,它会对值进行排序,以确保日期排序。但这取决于您DataFrame中出现的每个日期至少一次。否则,您将需要以某种方式创建订购日期列表。

答案 1 :(得分:1)

首先将date转换为datetime格式:

df.Date = pd.to_datetime(df.Date, format='%Y%m%d')

您可以使用现有日期创建每周pd.date_range

ix = pd.date_range(df.Date.min(), df.Date.max() + pd.DateOffset(1), freq="W")

接下来的步骤将是根据创建的日期范围GorupBy SKUreindex,并根据列ffill和{{ 1}},将bfillNaNs填充为SKU0的所有Demand

Supply

最后一步是连接两个数据帧,并采用df1 = (df.set_index('Date').groupby('SKU').apply(lambda x: x.reindex(ix)[['SKU']]) .ffill().bfill().reset_index(0, drop=True)) df2 = (df.set_index('Date').groupby('SKU').apply(lambda x: x.reindex(ix)[['Demand','Supply']]) .fillna(0).reset_index(0, drop=True)) cumsum中的Demand

Supply