Python组百分比变化

时间:2020-07-07 04:01:41

标签: python pandas pandas-groupby

我想获取Value1和Value 2的按年季度变化

df =\
pd.DataFrame({'Year':[2010,2010,2010,2010,2009,2009,2009,2009],
              'Quarter':[1,1,2,2,1,1,2,2],
              'Section':['A', 'B', 'A', 'B','A', 'B','A', 'B'],
              'Value1': [1,2,3,4,5,6,7,8],
              'Value2':[10,20,30,40,50,60,70,80]
             })
df.set_index(['Year', 'Quarter', 'Section'], inplace=True)
df

目前我正在这样做:

##Not ideal
df_2009 =\
(df
 .reset_index()
 .where(lambda x: x.Year == 2009)
 .dropna()
 .astype({'Quarter':'int16'})
 .set_index(['Quarter', 'Section'])
 .drop('Year', axis=1)
)

df_2010 =\
(df
 .reset_index()
 .where(lambda x: x.Year == 2010)
 .dropna()
 .astype({'Quarter':'int16'})
 .set_index(['Quarter', 'Section'])
 .drop('Year', axis=1)
)
 
df_2010/df_2009

但是,它不可扩展。我想知道有更好的方法来做到这一点。例如熊猫函数或UDF

p.s。结果是由

创建的
(somedata
.groupby(['Year', 'Quarter', 'Section'])
.agg({'Value1':'sum',
      'Value2':'sum'})
)

2 个答案:

答案 0 :(得分:2)

您在寻找这样的东西吗?

df.groupby(['Quarter','Section']).pct_change(-1)

输出:

                        Value1    Value2
Year Quarter Section                    
2010 1       A       -0.800000 -0.800000
             B       -0.666667 -0.666667
     2       A       -0.571429 -0.571429
             B       -0.500000 -0.500000
2009 1       A             NaN       NaN
             B             NaN       NaN
     2       A             NaN       NaN
             B             NaN       NaN

答案 1 :(得分:0)

使用pct_change的另一种方式不如@QuangHoang的回答那么优雅。最后加上+1和.dropna()与运行代码的预期输出匹配。但是,我保留了Year列,因为如果您还有更多的年数(除了它与您运行代码的输出相同),将需要该列:

a = df.sort_values(['Section', 'Quarter', 'Year']). \
groupby(['Section', 'Quarter']). \
agg({'Value1' : 'pct_change', 'Value2' : 'pct_change'}). \
dropna().sort_values('Quarter') + 1
a

输出:

                        Value1      Value2
Year    Quarter Section     
2010    1       A       0.200000    0.200000
                B       0.333333    0.333333
        2       A       0.428571    0.428571
                B       0.500000    0.500000