使用带有datetime对象的pandas Grouper方法的奇怪行为

时间:2018-05-30 04:15:01

标签: python pandas datetime group-by pandas-groupby

我正在尝试在另一列的组中创建x天组。出于某种原因,当我添加另一级别的分组时,分组行为已更改

见下面的玩具示例:

创建一个包含40个连续日期,ID列和随机值的随机数据框:

import numpy as np
import pandas as pd
df = pd.DataFrame(
        {'dates':pd.date_range('2018-1-1',periods=40,freq='D'),
         'id': np.concatenate((np.repeat(1,10),np.repeat(2,30))),
         'amount':np.random.random(40)
         }
)

我希望先按id进行分组,然后在这些群组中连续7天组成小组。我这样做:

(df
 .groupby(['id',pd.Grouper(key='dates',freq='7D')])
 .amount
 .agg(['mean','count'])
)

输出是:

                   mean  count
id dates                      
1  2018-01-01  0.591755      7
   2018-01-08  0.701657      3
2  2018-01-08  0.235837      4
   2018-01-15  0.650085      7
   2018-01-22  0.463854      7
   2018-01-29  0.643556      7
   2018-02-05  0.459864      5

第二组中有一些奇怪的事情发生了!我希望看到4组7,然后是最后一组2.当我在只有id=2的数据帧上运行相同的代码时,我得到了我真正期望的内容:

df2=df[df.id==2]

(df2
 .groupby(['id',pd.Grouper(key='dates',freq='7D')])
 .amount
 .agg(['mean','count'])
)

输出

                   mean  count
id dates                      
2  2018-01-11  0.389343      7
   2018-01-18  0.672550      7
   2018-01-25  0.486620      7
   2018-02-01  0.520816      7
   2018-02-08  0.529915      2

这里发生了什么?它是否首先在id=2组中创建一个4人组,因为id=1组中的最后一个组只有3行?这不是我想做的!

1 个答案:

答案 0 :(得分:2)

当您使用这两个ID进行分组时,当您执行每周分组时,您会从第一个组溢出到第二个分组(因为上周没有足够的天数来完成组#1中的完整7天)。当您查看每组的第一个日期时,这很明显:

" 2018年1月8日"在第一种情况下v / s" 2018-01-11"。

解决方法是在groupby上执行id,然后在apply执行重新采样操作:

df.groupby('id').apply(
    lambda x: x.set_index('dates').amount.resample('7D').count()
)

id  dates     
1   2018-01-01    7
    2018-01-08    3
2   2018-01-11    7
    2018-01-18    7
    2018-01-25    7
    2018-02-01    7
    2018-02-08    2
Name: amount, dtype: int64