2017-05-30 87 views
2

我正在使用这里显示的示例中的数据: http://pandas.pydata.org/pandas-docs/stable/groupby.html。转到子标题:窗口和重新取样操作的新语法大熊猫groupby扩展语法优化

在命令提示符处,新语法的工作方式如熊猫文档中所示。但是我希望将扩展数据的新列添加到现有数据框中,就像在保存的程序中那样。

语法升级到GROUPBY扩展代码之前,我可以使用下面的一行代码:

df = pd.DataFrame({'A': [1] * 10 + [5] * 10, 'B': np.arange(20)}) 
df['Sum of B'] = df.groupby('A')['B'].transform(lambda x: pd.expanding_sum(x)) 

这给了预期的效果,而且还给出了一个“expanding_sum已过时”的消息。预期结果如下:

A B Sum of B 
0 1 0   0 
1 1 1   1 
2 1 2   3 
3 1 3   6 
4 1 4  10 
5 1 5  15 
6 1 6  21 
7 1 7  28 
8 1 8  36 
9 1 9  45 
10 5 10  10 
11 5 11  21 
12 5 12  33 
13 5 13  46 
14 5 14  60 
15 5 15  75 
16 5 16  91 
17 5 17  108 
18 5 18  126 
19 5 19  145 

我想使用新的语法来替换弃用的语法。如果我尝试新的语法,我得到错误信息:

df['Sum of B'] = df.groupby('A').expanding().B.sum() 

TypeError: incompatible index of inserted column with frame index 

我做了一些搜索放在这里,和看到的东西,可能有帮助,但它给了我不同的信息:

df['Sum of B'] = df.groupby('A').expanding().B.sum().reset_index(level = 0) 

ValueError: Wrong number of items passed 2, placement implies 1 

我可以得到它的工作的唯一办法是将结果分配给一个临时DF,然后将临时DF合并到原始DF:

temp_df = df.groupby('A').expanding().B.sum().reset_index(level = 0).rename(columns = {'B' : 'Sum of B'}) 
new_df = pd.merge(df, temp_df, on = 'A', left_index = True, right_index = True) 
print (new_df) 

该代码给出了预期的效果,如上图所示。

我已经尝试了使用变换的不同变体,但一直没有能够像在弃用之前那样在一行中编写代码。是否有单行的语法可以工作?谢谢。

+0

'df ['B'的和] = df.groupby('A')。cumsum()' – AChampion

+0

@AChampion:如果这意味着要回答问题,请将其添加为答案。 – DSM

+0

谢谢,这个作品。我不确定是否需要为这个问题提出一个新问题,但在上面的例子中,'滚动'代替'扩展'和'平均'代替'总和'。 cumsum有没有相当于“rollmean”的?如果不是,我的问题仍然适用于'滚动'和'平均'。如果我不得不问一个新问题,我会的。 – BPowers97

回答

0

看来你需要一个cumsum:

df.groupby('A')['B'].cumsum() 
+0

谢谢@AChampion。已经更新了答案并在列中保留了'B'列以防DF中有更多的列。 – Allen

0

TL; DR

df['Sum of B'] = df.groupby('A')['B'].transform(lambda x: x.expanding().sum()) 

说明

我们从问题的行开始:

df.groupby('A')['B'].transform(lambda x: pd.expanding_sum(x)) 

让我们仔细阅读警告你提到:

FutureWarning:pd.expanding_sum已被弃用为系列和将是 在将来的版本中删除,替换 Series.expanding(min_periods = 1)的.sum()

读取后Pandas 0.17.0: pandas.expanding_sum很明显,Series警告提到的是pd.expanding_sum的第一个参数。即在我们的案例中是x

现在我们应用警告中建议的代码转换。所以pd.expanding_sum(x)变成x.expanding(min_periods=1).sum()

根据Pandas 0.22.0: pandas.Series.expandingmin_periods有一个默认值1所以在你的情况下,它可以完全省略,因此最终的结果。