pandas pd.grouper将datetime键与另一个分组键结合使用,似乎创建了错误的组数

mm5n2pyu  于 2023-02-07  发布在  其他
关注(0)|答案(2)|浏览(148)

将带有datetime键的pd.Grouper与另一个键结合使用可以创建一组组,但在我看来,这似乎并不包含需要创建的所有组。

>>> test = pd.DataFrame({"id":["a","b"]*3, "b":pd.date_range("2000-01-01","2000-01-03", freq="9H")})
>>> test
    id  b
0   a   2000-01-01 00:00:00
1   b   2000-01-01 09:00:00
2   a   2000-01-01 18:00:00
3   b   2000-01-02 03:00:00
4   a   2000-01-02 12:00:00
5   b   2000-01-02 21:00:00

当我尝试根据日期和id值创建组时:

>>> g = test.groupby([pd.Grouper(key='b', freq="D"), 'id'])
>>> g.groups
{(2000-01-01 00:00:00, 'a'): [0], (2000-01-02 00:00:00, 'b'): [1]}

g.groups只显示了2个组,而我预期为4个组:“a”和“b”代表每一天。
然而,当我基于“b”创建另一列时:

>>> test['date'] = test.b.dt.date
>>> g = test.groupby(['date', 'id'])
>>> g.groups
{(2000-01-01, 'a'): [0, 2], (2000-01-01, 'b'): [1], (2000-01-02, 'a'): [4], (2000-01-02, 'b'): [3, 5]}

结果和我预料的完全一样。
我不知道如何理解这些不同的结果,请你开导我。

y4ekin9u

y4ekin9u1#

您确实有4个组使用Grouperg.groups的输出具有误导性(可能值得作为bug报告?):

g = test.groupby([pd.Grouper(key='b', freq="D"), 'id'])

g.ngroups
# 4

g.size()
# b           id
# 2000-01-01  a     2
#             b     1
# 2000-01-02  a     1
#             b     2
# dtype: int64
1szpjjfi

1szpjjfi2#

我相信这是因为'pd.Grouper'和pandas中的'dt.date'方法之间的差异。'pd.Grouper'按一系列值(例如,每天、每小时等)分组,而'dt.date'只返回datetime对象的日期部分,有效地创建了一个分类变量。
当您以“D”的频率使用'pd.Grouper'时,它将按完整的天进行分组,因此每天仅由一个组表示。但在您的情况下,每个ID对于给定的天具有多个记录。因此,'pd.Grouper'无法捕获您期望的所有组。
另一方面,当您使用'dt.date'方法提取datetime的日期部分时,它会创建一个独立表示每个日期的分类变量。
因此,当您按照这个新的date列沿着id列进行分组时,每个组将对应于date和id的唯一组合,从而得到预期的结果。
总之,当您希望按一定范围的值(例如,每天、每小时)进行分组时,pd.Grouper非常有用;而当您希望按特定值进行分组时,使用单独的列来存储精确值(例如,仅存储日期的列)非常有用。

相关问题