尝试使用 pandas 数据框中其他两列的 groupby 创建基于另一列的新滚动平均列时出错

问题描述

我正在尝试在数据框中的“cum_year_WHIP”列中创建一个名为“MA3_WHIP”的移动平均线(窗口=3)的新列。我尝试了以下代码来实现它:

read_and_optimized['MA3_WHIP'] = read_and_optimized['cum_year_WHIP'].rolling(3).mean()

但出于某种原因,这并没有给我想要的滚动平均值。

在创建 'cum_year_WHIP' 列之前,我按 'YEAR_ID' 和 'Game_date' 对 df 进行了排序:

read_and_optimized.sort_values(['YEAR_ID','Game_Date'],ascending=True,inplace=True)

然后我创建了 'cum_year_WHIP' 列,该列是新滚动平均列 'MA3_WHIP' 所基于的列,并通过在其他三个列之间的数学上使用 cumsum() 进行计算 ((cum_walks_a + cum_hits_a)/cum_innings_pitched) :

read_and_optimized['cum_year_WHIP'] =(read_and_optimized['cum_year_walks_a'] + read_and_optimized['cum_year_hits_a'])/ read_and_optimized['cum_year_innings_pitched']

特别是,我希望“MA3_WHIP”按“YEAR_ID”和“Game_Date”列排序,就像“cum_year_WHIP”列一样,并按“resp_starting_pitcher”和“YEAR_ID”列分组.

要打印出表格的样子,我使用以下代码

df=read_and_optimized[['YEAR_ID','Game_Date','resp_starting_pitcher','cum_year_WHIP','MA3_WHIP']].sort_values(['YEAR_ID',ascending=True).groupby(['resp_starting_pitcher','YEAR_ID']).apply(print)

它给了我这个不需要的输出

    YEAR_ID  Game_Date resp_starting_pitcher  cum_year_WHIP  MA3_WHIP
30677     2012 2012-08-25              abadf001       2.000000  1.438035
19247     2012 2012-08-31              abadf001       2.280009  1.547771
35725     2012 2012-09-05              abadf001       2.270277  1.622140
19257     2012 2012-09-12              abadf001       2.234052  1.736054
42448     2012 2012-09-18              abadf001       1.983877  1.646596
19273     2012 2012-09-24              abadf001       1.880600  1.444433
       YEAR_ID  Game_Date resp_starting_pitcher  cum_year_WHIP  MA3_WHIP
6930      2011 2011-05-21              aceva001       1.000000  1.257886
17000     2011 2011-05-26              aceva001       1.090909  1.228938
6936      2011 2011-05-31              aceva001       1.437500  1.554379
6954      2011 2011-06-21              aceva001       1.571429  1.710058

相反,我想得到的是 'cum_year_WHIP' 的滚动平均值,它从每个新的 'resp_starting 投手' 开始,并在每个新的 'YEAR_ID' 开始。它应该是这样的:

   YEAR_ID  Game_Date resp_starting_pitcher  cum_year_WHIP  MA3_WHIP
30677     2012 2012-08-25              abadf001       2.000000  Nan
19247     2012 2012-08-31              abadf001       2.280009  Nan
35725     2012 2012-09-05              abadf001       2.270277  2.183428
19257     2012 2012-09-12              abadf001       2.234052  2.261446
42448     2012 2012-09-18              abadf001       1.983877  2.162735
19273     2012 2012-09-24              abadf001       1.880600  2.032843

       YEAR_ID  Game_Date resp_starting_pitcher  cum_year_WHIP  MA3_WHIP
6930      2011 2011-05-21              aceva001       1.000000  Nan
17000     2011 2011-05-26              aceva001       1.090909  Nan
6936      2011 2011-05-31              aceva001       1.437500  1.171613
6954      2011 2011-06-21              aceva001       1.571429  1.366612

       YEAR_ID  Game_Date resp_starting_pitcher  cum_year_WHIP  MA3_WHIP
7210      2013 2013-04-11              aceva001       1.800000  Nan
13938     2013 2013-04-17              aceva001       1.900000  Nan
7226      2013 2013-04-23              aceva001       2.250006  1.983333
7260      2013 2013-05-27              aceva001       2.068969  2.072991
44210     2013 2013-06-12              aceva001       1.894739  2.071238
7276      2013 2013-06-18              aceva001       1.780222  1.914643

当我使用以下内容时,它可以生成表格外观的视图: read_and_optimized.groupby(['resp_starting_pitcher','YEAR_ID'])['cum_year_WHIP'].rolling(3).mean() 但是,当我按照其他类似问题的帖子中的建议尝试从上述代码创建一个新列时,它给了我一个错误

read_and_optimized['MA3_WHIP']= read_and_optimized.groupby(['resp_starting_pitcher','YEAR_ID'])['cum_year_WHIP'].rolling(window=3).mean()

错误是:

TypeError: incompatible index of inserted column with frame index

有没有办法在数据框中创建这个新列?

我在以下位置查看了类似困境的答案:Why is groupby and rolling not working together?

在:Pandas - moving averages - use values of previous X entries for current row

但我无法完成。

帮助完成这项工作将不胜感激。

解决方法

好的,我终于找到了一个适用于我的情况的帖子来提供帮助。正如问题的回答中所指出的:https://stackoverflow.com/questions/52801540/pandas-groupby-then-rolling-meanI had to

需要重置 groupby 列的索引,在本例中为列 'resp_starting_pitcher' 和 'YEAR_ID',然后将它们放入代码中以创建新的滚动平均列:

read_and_optimized['MA3_WHIP']=read_and_optimized.groupby(['resp_starting_pitcher','YEAR_ID'])['cum_year_WHIP'].rolling(3).mean().reset_index(level = ('resp_starting_pitcher','YEAR_ID'),drop = True)