分组列上的分组,日期和期间产生意外结果

时间:2016-02-06 03:05:32

标签: python pandas

以下问题是在Python 2.7.11中使用Pandas 0.17.1

创建的

将分类列与期间和日期列分组时,分组中会显示意外的行。这是熊猫的错误​​,还是其他的东西?

df = pd.DataFrame({'date': pd.date_range('2015-12-29', '2016-1-3'), 
                   'val1': [1] * 6, 
                   'val2': range(6), 
                   'cat1': ['a', 'b', 'c'] * 2, 
                   'cat2': ['A', 'B', 'C'] * 2})
df['cat1'] = df.cat1.astype('category')
df['month'] = [d.to_period('M') for d in df.date]
>>> df
  cat1 cat2       date  val1  val2   month
0    a    A 2015-12-29     1     0 2015-12
1    b    B 2015-12-30     1     1 2015-12
2    c    C 2015-12-31     1     2 2015-12
3    a    A 2016-01-01     1     3 2016-01
4    b    B 2016-01-02     1     4 2016-01
5    c    C 2016-01-03     1     5 2016-01

使用常规系列(例如cat2)对月份和日期进行分组符合预期:

>>> df.groupby(['month', 'date', 'cat2']).sum().unstack()
                   val1         val2        
cat2                  A   B   C    A   B   C
month   date                                
2015-12 2015-12-29    1 NaN NaN    0 NaN NaN
        2015-12-30  NaN   1 NaN  NaN   1 NaN
        2015-12-31  NaN NaN   1  NaN NaN   2
2016-01 2016-01-01    1 NaN NaN    3 NaN NaN
        2016-01-02  NaN   1 NaN  NaN   4 NaN
        2016-01-03  NaN NaN   1  NaN NaN   5

但是对分类进行分组会产生意想不到的结果。您将在索引中注意到额外日期与分组月份不对应。

>>> df.groupby(['month', 'date', 'cat1']).sum().unstack()
                   val1         val2        
cat1                  a   b   c    a   b   c
month   date                                
2015-12 2015-12-29    1 NaN NaN    0 NaN NaN
        2015-12-30  NaN   1 NaN  NaN   1 NaN
        2015-12-31  NaN NaN   1  NaN NaN   2
        2016-01-01  NaN NaN NaN  NaN NaN NaN  # <<< Extraneous row.
        2016-01-02  NaN NaN NaN  NaN NaN NaN  # <<< Extraneous row.
        2016-01-03  NaN NaN NaN  NaN NaN NaN  # <<< Extraneous row.
2016-01 2015-12-29  NaN NaN NaN  NaN NaN NaN  # <<< Extraneous row.
        2015-12-30  NaN NaN NaN  NaN NaN NaN  # <<< Extraneous row.
        2015-12-31  NaN NaN NaN  NaN NaN NaN  # <<< Extraneous row.
        2016-01-01    1 NaN NaN    3 NaN NaN
        2016-01-02  NaN   1 NaN  NaN   4 NaN
        2016-01-03  NaN NaN   1  NaN NaN   5

按月份或日期对分类进行分组可以正常工作,但不能像上面的示例中那样进行组合。

>>> df.groupby(['month', 'cat1']).sum().unstack()
        val1       val2      
cat1       a  b  c    a  b  c
month                        
2015-12    1  1  1    0  1  2
2016-01    1  1  1    3  4  5

>>> df.groupby(['date', 'cat1']).sum().unstack() 
           val1         val2        
cat1          a   b   c    a   b   c
date                                
2015-12-29    1 NaN NaN    0 NaN NaN
2015-12-30  NaN   1 NaN  NaN   1 NaN
2015-12-31  NaN NaN   1  NaN NaN   2
2016-01-01    1 NaN NaN    3 NaN NaN
2016-01-02  NaN   1 NaN  NaN   4 NaN
2016-01-03  NaN NaN   1  NaN NaN   5

修改 此行为源于0.15.0更新。在此之前,这是输出:

>>> df.groupby(['month', 'date', 'cat1']).sum().unstack()
                    val1          val2        
cat1                   a   b   c     a   b   c
month   date                                  
2015-12 2015-12-29     1 NaN NaN     0 NaN NaN
        2015-12-30   NaN   1 NaN   NaN   1 NaN
        2015-12-31   NaN NaN   1   NaN NaN   2
2016-01 2016-01-01     1 NaN NaN     3 NaN NaN
        2016-01-02   NaN   1 NaN   NaN   4 NaN
        2016-01-03   NaN NaN   1   NaN NaN   5

1 个答案:

答案 0 :(得分:0)

正如大熊猫中所定义的,使用分类进行分组将始终拥有完整的类别集,即使没有该类别的任何数据,例如doc example here

您可以不使用分类,也可以在分组步骤后添加.dropna(how='all')