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

Python 带有datetime对象的pandas Grouper方法的奇怪行为,python,pandas,datetime,group-by,pandas-groupby,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

我试图在另一列的组中创建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
组中的最后一个组只有3行,所以首先在
id=2
组中创建一个4人组吗?这不是我想做的

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

第一个案例中的“2018-01-08”v/s“2018-01-11”

解决方法是对
id
执行
groupby
,然后
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

谢谢我试图避免应用lambda函数,但我想我们没有更好的方法了。@user4505419是的。。。不幸的是。你知道,在大多数情况下,你所拥有的会起作用,并且99%的时间是正确的。这只是这些边缘案例的一个问题。无论如何,
apply
对于大小合理的数据来说应该不会太慢。祝你好运。