如何使用更复杂的功能应用或转换

时间:2019-07-14 19:11:18

标签: python python-3.x pandas pandas-groupby

我对python和pandas还是比较陌生,我正在尝试使用Apply执行分组操作,但很难使其正常工作。

我的数据框如下:

Year    Country Val1    Val2    Fact
2005    A   1   3   1
2006    A   2   4   2
2007    A   3   5   2
2008    A   4   3   1
2009    A   4   3   1
2010    A   4   3   1
2005    B   5   7   2
2006    B   6   6   2
2007    B   7   5   1
2008    B   8   6   2
2009    B   8   6   2
2010    B   8   6   2

对于每年的每个国家,我需要计算 (2005-2008年的国家平均值-2005年的值)/ 4 *事实*(2005年)+ 2005年的值

到目前为止,我通读了apply和transform的用法,并研究了与两个函数的使用有关的问题(例如12),我认为可以通过以下方法解决我的问题:明智地运用。

我试图像这样设置它:

import pandas as pd

df = pd.DataFrame({'Year' : [2005, 2006, 2007, 2008, 2009, 2010, 2005, 2006, 2007, 2008, 2009, 2010],
                'Country' : ['A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B'],
                'Val1' : [1, 2, 3, 4, 4, 4, 5, 6, 7, 8, 8, 8],
                'Val2' : [3, 4, 5, 3, 3, 3, 7, 6, 5, 6, 6, 6,],
                'Fact' : [1, 2, 2, 1, 1, 1, 2, 2, 1, 2, 2, 2]
                    })

def func(grp):
    grad = grp[(grp['Year'] > 2004) & (grp['Year'] < 2009)].transform('mean')
    ref = grp[grp['Year'] == 2005]
    grad = (grad - ref)/4
    res = grad * grp['Fact'] * (grp['Year']-2015) * ref
    return res

df.groupby('Country').apply(func)

运行代码会产生

        Country Fact    Val1    Val2    Year    0   1   2   3   4   5   6   7   8   9   10  11
Country                                                                     
A   0   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
B   6   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

但是,我希望能收到与此类似的东西

Year  Country Val1    Val2    Fact
2005  A       1       3       1
2006  A       1.75    3.375   2
2007  A       2.5     3.75    2
2008  A       2.125   3.5625  1
2009  A       2.125   3.5625  1
2010  A       2.125   3.5625  1
2005  B       5       7       2
2006  B       5.75    6.5     2
2007  B       5.75    6.5     1
2008  B       7.25    5.5     2
2009  B       7.25    5.5     2
2010  B       7.25    5.5     2

如果有人能指出我的解决方案,我将不胜感激。

1 个答案:

答案 0 :(得分:0)

最好不要在一个函数内完成

s1=df.loc[df.Year.between(2005,2008)].groupby('Country').mean()[['Val1','Val2']]
s2=df.loc[df.Year.eq(2005),['Country','Val1','Val2']].set_index('Country')
s3=df.Year.sub(2005)*df.Fact
s=(s1-s2).div(4).reindex(df.Country).values*s3.values[:,None]+s2.reindex(df.Country).values
df.loc[:,['Val1','Val2']]=s
df
    Year Country   Val1    Val2  Fact
0   2005       A  1.000  3.0000     1
1   2006       A  1.750  3.3750     2
2   2007       A  2.500  3.7500     2
3   2008       A  2.125  3.5625     1
4   2009       A  2.500  3.7500     1
5   2010       A  2.875  3.9375     1
6   2005       B  5.000  7.0000     2
7   2006       B  5.750  6.5000     2
8   2007       B  5.750  6.5000     1
9   2008       B  7.250  5.5000     2
10  2009       B  8.000  5.0000     2
11  2010       B  8.750  4.5000     2