2016-12-30 36 views
1

Pandas中的一个人如何在同一数据集上进行多步/顺序聚合?就好像每一步都是下一个的“子查询”一样。熊猫数据框中的多步聚合

我可以在SQL认为它是这样的:

SELECT x.A, COUNT(x.B) as B_COUNT, SUM(x.C_SUM) as C_SUM 
FROM (
    SELECT df.A, df.B, SUM(df.C) as C_SUM 
    FROM df 
    GROUP BY df.A, df.B 
) x 
GROUP BY x.A 

在Python3.4和Pandas0.19.2工作,我有这样一个数据帧:

import pandas 
import numpy 

numpy.random.seed(1) 
df = pandas.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', 
          'foo', 'bar', 'foo', 'foo'], 
        'B' : ['one', 'one', 'two', 'three', 
          'two', 'two', 'one', 'three'], 
        'C' : numpy.random.randn(8), 
        'D' : numpy.random.randn(8)}) 

我试过汇总到A,B级,然后在那个数据帧上工作(也就是说,它的索引是'C',而列'A'由于它不在键列表中而引发KeyError

A_B_AGG = df.groupby(['A','B']).C.sum().to_frame() 
A_B_AGG.keys() 
#Index(['C'], dtype='object') 
#Would like to do this, but throws KeyError 
end_result = A_B_AGG.groupby('A').B.size() 

最终,我应该得到的东西,看起来像...

A B_COUNT  C_SUM 
bar  3 -3.986264 
foo  3 2.945186 

感谢您对这样做的正确,熊猫方式的任何指导!

回答

1

可以使用agg功能:

df.groupby('A').agg({'B': pandas.Series.nunique, 'C': 'sum'}) 

#    C B 
#A  
#bar -3.986264 3 
#foo  2.945186 3 

我认为这等同于您的SQL查询的原因是,当你被列A和B做组,那么就会出现在每个没有B的重复一个小组。因此,按A分组的B的计数将与按A分组的B的唯一计数相同;对于C sum,子组的总数与组的总和相同。


这是一个直接翻译你的SQL查询的,我认为逻辑上等同于上述方法:

(df.groupby(['A', 'B']).C.sum().reset_index() 
    .groupby('A').agg({'B': 'count', 'C': 'sum'})) 

#    C B 
# A  
#bar -3.986264 3 
#foo  2.945186 3 
+0

当你'C.sum()'会发生什么其他列? 'D'列会发生什么?当你做群组时,你可以聚合少数列并留下其他人吗? – MYGz

+1

@MYGz他们被忽略。当你做'groupby(...)。C'意味着你选择了“C”列和组变量。 – Psidom

+0

谢谢!所以如果我们想在不同的列上进行不同类型的聚合,我们必须使用'.agg()'。 – MYGz