Python 如何为groupby DataFrame创建滚动百分比

Python 如何为groupby DataFrame创建滚动百分比,python,pandas,Python,Pandas,我试图计算每个产品每月的百分比变化。这是我到目前为止所拥有的。我有一个涉及单个产品的数据框架。对于如何将计算应用到包含许多产品和许多月份的结果集,我感到困惑 数据帧示例: 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_

我试图计算每个产品每月的百分比变化。这是我到目前为止所拥有的。我有一个涉及单个产品的数据框架。对于如何将计算应用到包含许多产品和许多月份的结果集,我感到困惑

数据帧示例:

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”


任何关于如何正确计算的建议都将不胜感激

看起来,在小组内,每个月有一次观察,你需要从一个月到下一个月的百分比变化。您可以使用
groupby/apply
通过在“product_desc”上分组,然后使用内置的
pct_change()
方法来实现这一点:

>>> df['pct_ch'] = df.groupby('product_desc')['prod_count'].pct_change() + 1
注意,我在
pct\u 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)
>>> df['pct_ch'] = df.groupby('product_desc')['prod_count'].apply(lambda x: x/x.shift(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\u count']
,您没有对该列做任何操作

在较旧版本的
pandas
上,您可能必须执行以下操作:

>>> df['pct_ch'] = df.groupby('product_desc')['prod_count'].apply(lambda x: x.pct_change() + 1)
>>> df['pct_ch'] = df.groupby('product_desc')['prod_count'].apply(lambda x: x/x.shift(1))

您正在使用pandas 0.13.1的leatest版本吗?是的,这是pandas 0.13.1感谢您在这方面的帮助。pct_change函数正是我所需要的。但是,当我应用排序时,它们的排序方式不同。您是否先用strtime将活动_月转换为日期?我的结果是按产品描述排序的,但活动月份不符合顺序。我确实将
activity\u month
列转换为日期时间数据类型。您可以对这两种方法进行排序,以确保正确的排序:
df.sort(['product\u desc','activity\u month'])
我试过了,但没有成功。如果你想得到另一个答案,我在这里发布了一个类似的问题:这个解决方案在活动月不正常时不起作用。计算中断了。我在这里发布了一个新的问题,这个问题跟这个例子一样。