在 Pandas 中按组计算同比增长

Calculating year over year growth by group in Pandas

我有以下 dataframe:

In [1]: df
Out[1]: 

ID            Month           Transaction_Amount

1             2013/01         10
1             2013/02         20
1             2013/03         10
1             2013/04         20
1             2013/05         10
1             2013/06         20
1             2013/07         10
1             2013/08         20
1             2013/09         10
1             2013/10         20
1             2013/11         10
1             2013/12         20
1             2014/01         15
1             2014/02         25
1             2014/03         15
1             2014/04         25
...
1             2014/11         15
1             2014/12         25
...
10000000      2014/11         13
10000000      2014/12         23

我想做的是计算每年滚动月期间的增长,例如,我想找到 (2014/01 - 2013/01) / (2014/01) 的值 (15 - 10) / (15) = 1/3 并保存它对于第一个滚动周期。每个 ID 总共会有 12 个滚动周期。我认为最终输出应该是这样的:

In [2]: df_new
Out[2]: 

ID       rolling_period_1   rolling_period_2  ... rolling_period_12

1        .333333            .25                   .25
2        x1                 x2                    x12
3        y1                 y2                    y12
4        z1                 z2                    z12
...

我生成了一个列表,其中包含 [(2013/01, 2014/01), (2013/02, 2014/02) ... (2013/12, 2014/12)] 期间每年的元组,并且一直在使用 isin 来索引原始 df 的子集,但我不确定如何到达 df_new.

编辑

我使用以下代码创建了一个名为 temp_df 的新数据框:

In [4]: temp_df = df[df['month'].isin(('2013/01','2014/01'))]

In [5]: temp_df
Out[5]:

ID            Month           Transaction_Amount

1             2013/01         10
1             2014/01         15
2             2013/01         20
2             2014/01         30
3             2013/01         15
3             2014/01         30
...

我想要制作的是 DataFrame,如下所示:

In [6]: new_df
Out[6]:

ID            Transaction_Growth

1             .3333   # (15-10)/15
2             .3333   # (30-20)/30
3             .50     # (30-15)/30
...

您可以使用 shift 来偏移数据框中的行。

使用月列和值列创建虚拟数据

rng = pd.date_range('1/1/2011', periods=90, freq='M')
df = pd.DataFrame({'value':range(1,91),'date':rng})

将月份列设置为索引

df = df.set_index('date')

将数据帧的副本移动 12 个周期以获得 12 个月前的值,减去当前记录,然后除以当前记录:

df - df.shift(12)/ df

更新 shift 函数中句点的符号

已更新以考虑 ID

# Create range of months
rng = pd.date_range('1/1/2011', periods=180, freq='M')
ID = np.array([1,2,3])

# Create ID column
ID = np.repeat(ID,60)

# Create dummy data in dataframe
df = pd.DataFrame({'ID':ID,'value':range(1,181),'date':rng})

# Use shift on a group by object
(df.value - df.groupby(['ID']).value.shift(12))/ df.value

我认为有一种更简单的方法可以做到这一点,不需要跟踪变化的时间段,请尝试使用 df.pct_change() 方法:

import pandas as pd
import numpy as np
date_range = pd.period_range("2016-01", "2018-01",freq='m')
df= pd.DataFrame({'A':np.random.rand(len(date_range))}, index=date_range)
df['pct_pop'] = df['A'].pct_change()
df['pct_yoy'] = df['A'].pct_change(12)
df

               A    pct_pop     pct_yoy
2016-01 0.478381    NaN NaN
2016-02 0.941450    0.967991    NaN
2016-03 0.128445    -0.863567   NaN
2016-04 0.498623    2.882011    NaN
2016-05 0.914663    0.834377    NaN
2016-06 0.349565    -0.617821   NaN
2016-07 0.563296    0.611419    NaN
2016-08 0.144055    -0.744264   NaN
2016-09 0.502279    2.486708    NaN
2016-10 0.621283    0.236928    NaN
2016-11 0.716813    0.153763    NaN
2016-12 0.152372    -0.787431   NaN
2017-01 0.160636    0.054234    -0.664209
2017-02 0.496759    2.092453    -0.472347
2017-03 0.324318    -0.347132   1.524965
2017-04 0.431651    0.330949    -0.134315
2017-05 0.973095    1.254357    0.063884
2017-06 0.007917    -0.991864   -0.977351
2017-07 0.875365    109.562870  0.554005
2017-08 0.860987    -0.016425   4.976784
2017-09 0.099549    -0.884378   -0.801805
2017-10 0.544275    4.467398    -0.123950
2017-11 0.433326    -0.203846   -0.395482
2017-12 0.688057    0.587850    3.515636
2018-01 0.924038    0.342967    4.752374