使用numpy.median与其他函数聚合pandas groupby对象的结果不一致

时间:2012-09-29 09:37:40

标签: python numpy aggregate pandas

使用DataFrame(pandas as pd,numpy as np):

test = pd.DataFrame({'A' : [10,11,12,13,15,25,43,70],  
                     'B' : [1,2,3,4,5,6,7,8],  
                     'C' : [1,1,1,1,2,2,2,2]})


In [39]: test
Out[39]: 
    A  B  C
0  10  1  1
1  11  2  1
2  12  3  1
3  13  4  1
4  15  5  2
5  25  6  2
6  43  7  2
7  70  8  2

按“C”分组DF并与np.mean聚合(也是sum,min,max)会在组内产生逐列聚合:

In [40]: test_g = test.groupby('C')

In [41]: test_g.aggregate(np.mean)
Out[41]: 
       A    B
C            
1  11.50  2.5
2  38.25  6.5

然而,看起来使用np.median进行聚合会在组内产生数据框架聚合:

In [42]: test_g.aggregate(np.median)
Out[42]: 
      A     B
C            
1   7.0   7.0
2  11.5  11.5

(使用groupby.median方法似乎产生了预期的逐列结果)

我希望解决以下问题:

  1. 这种结果的原因/机制是什么?
  2. 如果确认此行为,它如何影响聚合分组的推荐“最佳做法”?其他聚合函数可以这样工作吗?

4 个答案:

答案 0 :(得分:4)

原因很有趣。可能一些大熊猫专家想要进入,但它归结为numpy和pandas之间的乒乓球。请注意,文档说:

  

用于聚合组的功能。如果是一个功能,必须要么   传递DataFrame或传递给DataFrame.apply时工作。如果   传递一个字典,键必须是DataFrame列名

第一个是2D(array_like),第二个方法归结为1D array_likes被传递给你给出的函数。

这意味着聚合首先传递2D系列。在第一种情况下(np.mean),numpy知道数组具有.mean属性,因此它执行它总是调用它的功能。但是它用axis=None调用它(默认为numpy)。这使得Pandas抛出一个Exception(它希望axis为0或1而且从不为None)并且它进入第二步,它将它作为1D传递并且是万无一失的。

然而,当您放入np.median numpy数组时,没有.median属性,所以它会执行正常的numpy机制,即展平数组(即通常为axis=None )。

解决方法是使用test_g.aggregate([np.median, np.median])强制它始终采用第二条路径。或者什么也可以工作:test_g.aggregate(np.median, axis=0)axis=0传递给np.median,从而告诉numpy如何正确处理它。一般来说,我想知道大熊猫是否应该至少不要发出警告,毕竟将结果广播到两个列应该几乎不是想要的。

答案 1 :(得分:1)

我怀疑这是一个错误......所以I added it here

同时(如果你原谅双关语),你可以使用.agg方法:

test_g.agg([np.mean,np.median])
        A             B        
     mean  median  mean  median
 C                             
 1  11.50    11.5   2.5     2.5
 2  38.25    34.0   6.5     6.5

答案 2 :(得分:1)

另外,请注意,pandas具有常用操作的快捷方法:

In [12]: test.groupby('C').mean()
Out[12]: 
       A    B
C            
1  11.50  2.5
2  38.25  6.5

In [13]: test.groupby('C').median()
Out[13]: 
      A    B
C           
1  11.5  2.5
2  34.0  6.5

对于诸如sum,mean,median,max,min,first,last,std之类的东西,您可以直接调用该方法,而不必担心apply-to-DataFrame-but-failover-to-each-column GroupBy引擎中的机制。

答案 3 :(得分:0)

从v 0.12开始引入DataFrame.median:http://pandas.pydata.org/pandas-docs/dev/generated/pandas.DataFrame.median.html

在0.12之前,我不认为该方法存在。相反,您可以使用numpy.median