为什么groupby.apply返回重复级别

时间:2016-08-15 01:57:02

标签: pandas

def afun(group):
  aa=len(group)
  group.sort_values(inplace=True)

  return pandas.DataFrame({'score':numpy.arange(aa),'price':group})



df = pandas.DataFrame({
              'stock':numpy.repeat( ['AAPL','GOOG','YHOO'], 3 ),
              'date':numpy.tile( pandas.date_range('5/5/2015', periods=3, freq='D'), 3 ),
              'price':(numpy.random.randn(9).cumsum() + 10) ,
              'price2':(numpy.random.randn(9).cumsum() + 10)})
df = df.set_index(['stock','date'])
agroupDf=df.groupby(level='date') 



tt=agroupDf['price'].apply(afun)

变量tt的值如图所示

我的问题是为什么tt有两列'date',以及如何避免secend列'date'?

enter image description here

3 个答案:

答案 0 :(得分:2)

第一个是groupby'日期'。第二个是index'日期'。

改变现状 - 这次groupby股票:

df       = df.set_index(['date','stock'])
agroupDf = df.groupby(level='stock') 

tt=agroupDf['price'].apply(afun)
tt


                            price  score
stock date       stock                  
AAPL  2015-05-05 AAPL    9.333143      0
      2015-05-06 AAPL    9.680022      1
      2015-05-07 AAPL    9.870889      2
GOOG  2015-05-06 GOOG   10.030032      0
      2015-05-05 GOOG   10.229084      1
      2015-05-07 GOOG   10.571631      2
YHOO  2015-05-07 YHOO    9.996925      0
      2015-05-05 YHOO   10.342180      1
      2015-05-06 YHOO   10.586120      2

我想你想要这个:

df       = df.set_index('stock')
agroupDf = df.groupby('date') 

tt=agroupDf['price'].apply(afun)
tt

                          price  score
date       stock                  
2015-05-05 AAPL   10.414396      0
           GOOG   12.608225      1
           YHOO   12.830496      2
2015-05-06 AAPL   10.428767      0
           GOOG   11.189663      1
           YHOO   11.988177      2
2015-05-07 YHOO   11.202677      0
           AAPL   11.274440      1
           GOOG   11.780654      2

答案 1 :(得分:0)

我也遇到了同样的问题,并找到了解决方案,尽管目前尚不清楚该解决方案是否适用,因为问题中引用的代码将为我返回错误。无论如何,这是一个玩具示例的设置:

import numpy as np
from pandas import DataFrame,Series

def my_func(group):
"""Demonstrator function for duplicate index"""
_sum = group[0].sum()
_mean = group[0].mean()
_median = group[0].median()
return DataFrame({'sum':_sum,'mean':_mean,'median':_median},
                 index=[group.first_valid_index()])

df = DataFrame(np.random.rand(10,5))
df.head()
    0   1   2   3   4
0   0.779801    0.704764    0.042028    0.831537    0.359437
1   0.515832    0.561174    0.530190    0.171031    0.927605
2   0.612827    0.730794    0.406032    0.192046    0.227649
3   0.698508    0.261531    0.919857    0.102664    0.506072
4   0.239987    0.871934    0.660110    0.402880    0.902426
df.groupby(level=0).apply(my_func)
         sum    mean    median
0   0   0.779801    0.779801    0.779801
1   1   0.515832    0.515832    0.515832
2   2   0.612827    0.612827    0.612827
3   3   0.698508    0.698508    0.698508
4   4   0.239987    0.239987    0.239987

首先,在DataFrame构造函数中不包括您选择的索引:

index=[group.first_valid_index()]

如果您的groupby函数在单列上运行,则应返回错误。由于某些原因,它没有多个列。在这种情况下,您将获得一个多索引而没有返回重复。

但是,在这里,我们只看一列,并包含了索引指针,并且显然返回了重复的索引。原来的解决方案是返回一个Series而不是Dataframe:

def my_func_series(group):
"""Demonstrator function for duplicate index"""
_sum = group[0].sum()
_mean = group[0].mean()
_median = group[0].median()
return Series({'sum':_sum,'mean':_mean,'median':_median})

现在,groupby.apply不返回重复的索引:

df.groupby(level=0).apply(my_func_series)
    sum mean    median
0   0.779801    0.779801    0.779801
1   0.515832    0.515832    0.515832
2   0.612827    0.612827    0.612827
3   0.698508    0.698508    0.698508
4   0.239987    0.239987    0.239987

由于DataFrame的每一行本身就是一个系列,并且您的目标是每个组返回一行,所以这很有意义。

答案 2 :(得分:0)

另一种方法是在 groupby 中设置 as_index = False,即:

agroupDf=df.groupby(level='date', as_index=False)

返回:

                    score     price
  stock date                       
0 YHOO  2015-05-05      0  5.021206
  GOOG  2015-05-05      1  7.544137
  AAPL  2015-05-05      2  9.153860
1 YHOO  2015-05-06      0  4.649305
  GOOG  2015-05-06      1  6.862662
  AAPL  2015-05-06      2  7.869256
2 GOOG  2015-05-07      0  6.149092
  YHOO  2015-05-07      1  6.269954
  AAPL  2015-05-07      2  8.185481

查看Pandas documentation了解详情。