如何为groupby DataFrame创建滚动百分比
我正在尝试计算每个产品按月的百分比变化。到目前为止,我已经有了一个只涉及单个产品的数据框的计算方法。但我现在不知道如何将这个计算应用到包含多个产品和多个月份的结果集中。
下面是一个示例数据框:
product_desc activity_month prod_count
product_a 1/1/2014 53
product_b 1/1/2014 42
product_c 1/1/2014 38
product_a 2/1/2014 26
product_b 2/1/2014 48
product_c 2/1/2014 39
product_a 3/1/2014 41
product_b 3/1/2014 35
product_c 3/1/2014 50
我需要得到的是一个数据框,里面增加了按产品描述和月份计算的百分比变化:
product_desc activity_month prod_count pct_change
product_a 1/1/2014 53
product_a 2/1/2014 26 0.490566038
product_a 3/1/2014 41 1.576923077
product_b 1/1/2014 42
product_b 2/1/2014 48 1.142857143
product_b 3/1/2014 35 0.729166667
product_c 1/1/2014 38
product_c 2/1/2014 39 1.026315789
product_c 3/1/2014 50 1.282051282
我可以用以下方法在一个只包含单个产品描述的数据框上计算这个:
df['change_rate1'] = df['prod_count'].shift(-1)/df['prod_count']
df['pct_change'] = df['change_rate1'].shift(1)
df = df.drop('change_rate1',1)
现在我尝试的是:
df_grouped = df.groupby(['product_desc','activity_month'])
for product_desc, activity_month in df_grouped:
df['change_rate1'] = df_grouped['prod_count'].shift(-1)/df_grouped['prod_count']
但是,在for语句的最后一行,我得到了一个'NotImplementedError'的错误。
如果有任何建议能让我正确计算这个,我会非常感激。
1 个回答
5
看起来在这些组里面,每个月都有一个数据点,你想要计算每个月之间的百分比变化。你可以通过使用 groupby/apply
来实现,先按照 'product_desc' 进行分组,然后使用内置的 pct_change()
方法:
>>> df['pct_ch'] = df.groupby('product_desc')['prod_count'].pct_change() + 1
注意,我在 pct_change()
方法里加了1,因为它计算的是净百分比变化。我会打印出一个排序后的版本,这样就能和你预期的结果匹配了:
>>> df.sort('product_desc')
product_desc activity_month prod_count pct_ch
0 product_a 2014-01-01 53 NaN
3 product_a 2014-02-01 26 0.490566
6 product_a 2014-03-01 41 1.576923
1 product_b 2014-01-01 42 NaN
4 product_b 2014-02-01 48 1.142857
7 product_b 2014-03-01 35 0.729167
2 product_c 2014-01-01 38 NaN
5 product_c 2014-02-01 39 1.026316
8 product_c 2014-03-01 50 1.282051
在旧版本的 pandas
中,你可能需要这样做:
>>> df['pct_ch'] = df.groupby('product_desc')['prod_count'].apply(lambda x: x.pct_change() + 1)
或者你可以像你建议的那样使用 shift,只需稍作修改:
>>> df['pct_ch'] = df['prod_count'] / df.groupby('product_desc')['prod_count'].shift(1)
>>> df.sort('product_desc')
product_desc activity_month prod_count pct_ch
0 product_a 2014-01-01 53 NaN
3 product_a 2014-02-01 26 0.490566
6 product_a 2014-03-01 41 1.576923
1 product_b 2014-01-01 42 NaN
4 product_b 2014-02-01 48 1.142857
7 product_b 2014-03-01 35 0.729167
2 product_c 2014-01-01 38 NaN
5 product_c 2014-02-01 39 1.026316
8 product_c 2014-03-01 50 1.282051
在 groupby
中,你不需要引用 df['prod_count']
,因为你并没有对那个列做任何操作。
在旧版本的 pandas
中,你可能需要这样做:
>>> df['pct_ch'] = df.groupby('product_desc')['prod_count'].apply(lambda x: x/x.shift(1))