【问题标题】:How to create rolling percentage for groupby DataFrame如何为 groupby DataFrame 创建滚动百分比
【发布时间】:2014-07-08 02:20:52
【问题描述】:

我正在尝试计算每种产品的月变化百分比。这是我到目前为止所拥有的。我有这个为涉及单个产品的 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 百分比变化的数据框:

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

我可以在具有单个 product_desc 的数据帧上计算这个:

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”。

感谢任何有关如何正确计算此值的建议。

【问题讨论】:

  • 您使用的是最新版本的 pandas 0.13.1 吗?
  • 是的,这是熊猫 0.13.1

标签: python pandas


【解决方案1】:

嗯,看起来像在组内,每个月有一次观察,你想要从一个月到下一个月的百分比变化。您可以使用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))

【讨论】:

  • 感谢您对此的帮助。 pct_change 函数正是我所需要的。但是,当我应用排序时,它们的排序方式不同。您是否先将 activity_month 转换为带有 strptime 的日期?我的结果按 product_desc 排序,但 activity_month 不正确。
  • 我确实将 activity_month 列转换为 datetime dtype。您可以对两者进行排序以确保正确排序:df.sort(['product_desc','activity_month'])
  • 我试过了,但没有用。如果您想获得另一个答案,我在这里发布了类似的问题:stackoverflow.com/questions/23771165/…
  • activity_month 不正常时,此解决方案不起作用。计算中断。我在此处发布了一个新问题,该问题遵循相同的示例。 stackoverflow.com/questions/23790415/…
猜你喜欢
  • 1970-01-01
  • 2017-03-18
  • 1970-01-01
  • 2019-05-15
  • 2018-04-04
  • 2022-06-13
  • 2016-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多