首页 > 解决方案 > 使用 Groupby 的 Pandas 窗口未按预期工作

问题描述

我有一个 pandas 数据框,我试图在按列分组后计算一个扩展的窗口聚合。数据结构是这样的:

df = pd.DataFrame([['A',1,2015,4],['A',1,2016,5],['A',1,2017,6],['B',1,2015,10],['B',1,2016,11],['B',1,2017,12],
               ['A',1,2015,24],['A',1,2016,25],['A',1,2017,26],['B',1,2015,30],['B',1,2016,31],['B',1,2017,32],
              ['A',2,2015,4],['A',2,2016,5],['A',2,2017,6],['B',2,2015,10],['B',2,2016,11],['B',2,2017,12]],columns=['Typ','ID','Year','dat'])\
.sort_values(by=['Typ','ID','Year'])

IE

    Typ ID  Year    dat
0   A   1   2015    4
6   A   1   2015    24
1   A   1   2016    5
7   A   1   2016    25
2   A   1   2017    6
8   A   1   2017    26
12  A   2   2015    4
13  A   2   2016    5
14  A   2   2017    6
3   B   1   2015    10
9   B   1   2015    30
4   B   1   2016    11
10  B   1   2016    31
5   B   1   2017    12
11  B   1   2017    32
15  B   2   2015    10
16  B   2   2016    11
17  B   2   2017    12

我需要按列Type和对这个数据框进行分组ID,然后通过 计算所有观察值的扩展平均值Year。我写的代码是

df.groupby(by=['Typ','ID','Year']).expanding().mean().reset_index()

我期望从中得到这样的输出结果(忽略level_3):

    Typ ID  Year    level_3 dat
0   A   1   2015    6   14.0
1   A   1   2016    7   14.5
2   A   1   2017    8   15.0
3   A   2   2015    12  4.0
4   A   2   2016    13  4.5
5   A   2   2017    14  5.0
6   B   1   2015    9   20.0
7   B   1   2016    10  20.5
8   B   1   2017    11  21.0
9   B   2   2015    15  10.0
10  B   2   2016    16  10.5
11  B   2   2017    17  11.0

分组依据['Type','ID','Year']应为这些列的每个唯一行生成一行。相反,代码给出了这个:

Typ ID  Year    level_3 dat
0   A   1   2015    0   4.0
1   A   1   2015    6   14.0
2   A   1   2016    1   5.0
3   A   1   2016    7   15.0
4   A   1   2017    2   6.0
5   A   1   2017    8   16.0
6   A   2   2015    12  4.0
7   A   2   2016    13  5.0
8   A   2   2017    14  6.0
9   B   1   2015    3   10.0
10  B   1   2015    9   20.0
11  B   1   2016    4   11.0
12  B   1   2016    10  21.0
13  B   1   2017    5   12.0
14  B   1   2017    11  22.0
15  B   2   2015    15  10.0
16  B   2   2016    16  11.0
17  B   2   2017    17  12.0

考虑到逻辑,expanding()窗口函数似乎没有groupby正确工作,或者至少它的行为不像我预期的那样。我究竟做错了什么?

编辑:我现在看到我做错了什么,因为我期待groupbyexpanding. 所以现在我的问题是如何使用 pandas 来获得我想要的输出 - 无需任何手动迭代。

标签: pythonpandaswindowing

解决方案


据我所知,扩展均值有不同的计算方式。对于您想要的输出,我将使用groupbyand的组合执行以下操作,然后在andcumsum之间进行简单的划分:sumcount

newDf = df.groupby(['Typ','ID','Year'])['dat'].agg(('sum', 'count')).groupby(['Typ','ID']).cumsum()
newDf['dat'] = newDf['sum']/newDf['count']
newDf = newDf.reset_index().drop(['count', 'sum'], axis = 1)

输出:

   Typ  ID  Year   dat
0    A   1  2015  14.0
1    A   1  2016  14.5
2    A   1  2017  15.0
3    A   2  2015   4.0
4    A   2  2016   4.5
5    A   2  2017   5.0
6    B   1  2015  20.0
7    B   1  2016  20.5
8    B   1  2017  21.0
9    B   2  2015  10.0
10   B   2  2016  10.5
11   B   2  2017  11.0

推荐阅读