2015-10-26 47 views
0

我有一個包含不同的產品每週的銷售數據幀(A,B,C):條件的總和

In[1] 
df = pd.DataFrame({'product': list('aaaabbbbcccc'), 
       'week': [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4], 
       'sales': np.power(2, range(12))}) 
Out[1] 
    product sales week 
0  a  1  1 
1  a  2  2 
2  a  4  3 
3  a  8  4 
4  b  16  1 
5  b  32  2 
6  b  64  3 
7  b 128  4 
8  c 256  1 
9  c 512  2 
10  c 1024  3 
11  c 2048  4 

我想創建一個包含了累計銷售新列最後n周,按產品分組。例如。對於n=2應該像last_2_weeks

product sales week last_2_weeks 
0  a  1  1    0 
1  a  2  2    1 
2  a  4  3    3 
3  a  8  4    6 
4  b  16  1    0 
5  b  32  2   16 
6  b  64  3   48 
7  b 128  4   96 
8  c 256  1    0 
9  c 512  2   256 
10  c 1024  3   768 
11  c 2048  4   1536 

我怎樣纔能有效地計算在熊貓這樣一個累積性的,有條件的總和?如果有更多的變量需要分組,例如,解決方案也應該工作。產品和位置。

我已經嘗試創建一個新函數,並使用groupbyapply,但這隻適用於行排序。它也很慢很醜。

def last_n_weeks(x): 
    """ calculate sales of previous n weeks in aggregated data """ 
    n = 2 
    cur_week = x['week'].iloc[0] 
    cur_prod = x['product'].iloc[0] 
    res = np.sum(df['sales'].loc[((df['product'] == cur_prod) & 
         (df['week'] >= cur_week-n) & (df['week'] < cur_week))]) 
    return res 

df['last_2_weeks'] = df.groupby(['product', 'week']).apply(last_n_weeks).reset_index(drop=True) 

回答

2

你可以使用pd.rolling_sumwindow=2,然後shift一次,用0

In [114]: df['l2'] = (df.groupby('product')['sales'] 
         .apply(lambda x: pd.rolling_sum(x, window=2, min_periods=0) 
         .shift() 
         .fillna(0))) 
In [115]: df 
Out[115]: 
    product sales week l2 
0  a  1  1  0 
1  a  2  2  1 
2  a  4  3  3 
3  a  8  4  6 
4  b  16  1  0 
5  b  32  2 16 
6  b  64  3 48 
7  b 128  4 96 
8  c 256  1  0 
9  c 512  2 256 
10  c 1024  3 768 
11  c 2048  4 1536 
+0

感謝填寫NaNs。與我的自定義功能相比,清晰的解決方案和更快。需要按「周」對數據框進行排序。 – malte