我有一个数据框,其中包含不同产品的每周销售额(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
如何在熊猫中有效地计算出这种累积的条件总和?如果有更多变量要分组,解决方案也应该有用,例如产品和地点。
我尝试过创建一个新函数并使用groupby
和apply
,但这仅适用于行的排序。它也很慢而且丑陋。
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)
答案 0 :(得分:2)
您可以将pd.rolling_sum
与window=2
一起使用,然后shift
使用NaNs
,并将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
service.shutdown()