【问题标题】:How to use apply or transform with a more complex function如何使用更复杂的函数应用或转换
【发布时间】:2019-11-23 14:27:19
【问题描述】:

我对 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),我认为我的问题可以通过使用 group wise 来解决申请。

我试着这样设置:

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

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

【问题讨论】:

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


    【解决方案1】:

    最好不要在一个函数中这样做

    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
    

    【讨论】:

      猜你喜欢
      • 2021-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-10
      • 1970-01-01
      • 2020-08-06
      相关资源
      最近更新 更多