pandas groupby 一天中的时间,带 15 分钟的垃圾箱

Posted

技术标签:

【中文标题】pandas groupby 一天中的时间,带 15 分钟的垃圾箱【英文标题】:pandas groupby time of day with 15 minute bins 【发布时间】:2021-04-25 11:46:47 【问题描述】:

我有一些跨越多天的时间序列数据,如下所示:

dr = pd.date_range('01-01-2020 9:00', '01-03-2020 23:59', freq='1T')
df = pd.DataFrame('data': 1, index=dr) # all ones in the data column

我有兴趣按一天中的时间分组并对数据求和(即跨日期合并数据)。我从this post 和this one 得知,您可以使用日期时间序列或索引的时间属性将数据分组到一天中的某个小时,如下所示:

df.groupby(df.index.hour).sum()
df.groupby(df.index.time).sum()

但是,我想分组为 15 分钟的垃圾箱,例如像这样(数字是任意的):

      data
00:00   10
00:15   12
00:30   15
...
11:30   16
11:45   20

请注意,我不想只进行 15 分钟的重新采样(例如 df.resample('15T').sum()),因为这不会对几天内的相似时间进行分组。因此,例如,任何日期 9:00 到 9:15 之间的数据都应该放在同一个 bin 中。

我找不到可以实现此目的的时间属性。我该怎么做?

【问题讨论】:

dfX = df.groupby(pd.Grouper(freq='15Min')).aggregate(numpy.sum) @JoeFerndz 没有将不同日期的同一时间放入同一个 bin。因此,就像 1 日 9:00 和 2 日 9:00 被放置在单独的垃圾箱中(不是我想要的)。抱歉,如果不清楚,我更新了我的帖子 所以你的输入可能是 00:01 3, 00:02 4, 00:008 2, 00:14 2, 00:20 5... 那么你希望 00:15 是 (3 + 4 + 2 = 9)?这必须在同一天。所以今天晚上 9 点应该放在一起,而不是和昨天晚上 9 点混在一起 @JoeFerndz,在您的示例中,您列出的前四次都发生在午夜和 12:15 之间,因此它们都应该被分箱,所以您应该得到 00:00 11 (3+4+2 +2)。但最后一部分听起来不正确,我确实希望今天的晚上 9 点与昨天的晚上 9 点混在一起。我想查看所有时间戳,就好像它们在同一日期一样,然后在 15 分钟时重新采样,这样我就可以看到例如平均晚上 9 点在几天内的样子。到目前为止,这两个答案似乎都是正确的 【参考方案1】:

尝试使用以下方法:

df.index = pd.to_datetime(df.index.time, format='%H:%M:%S')
print(df.resample('15T').sum())

输出:

                     data
1900-01-01 00:00:00    31
1900-01-01 00:15:00    30
1900-01-01 00:30:00    30
1900-01-01 00:45:00    30
1900-01-01 01:00:00    30
1900-01-01 01:15:00    30
1900-01-01 01:30:00    30
1900-01-01 01:45:00    30
1900-01-01 02:00:00    30
1900-01-01 02:15:00    30
1900-01-01 02:30:00    30
1900-01-01 02:45:00    30
1900-01-01 03:00:00    30
1900-01-01 03:15:00    30
1900-01-01 03:30:00    30
1900-01-01 03:45:00    30
1900-01-01 04:00:00    30
1900-01-01 04:15:00    30
1900-01-01 04:30:00    30
1900-01-01 04:45:00    30
1900-01-01 05:00:00    30
1900-01-01 05:15:00    30
1900-01-01 05:30:00    30
1900-01-01 05:45:00    30
1900-01-01 06:00:00    30
1900-01-01 06:15:00    30
1900-01-01 06:30:00    30
1900-01-01 06:45:00    30
1900-01-01 07:00:00    30
1900-01-01 07:15:00    30
...                   ...
1900-01-01 16:30:00    45
1900-01-01 16:45:00    45
1900-01-01 17:00:00    45
1900-01-01 17:15:00    45
1900-01-01 17:30:00    45
1900-01-01 17:45:00    45
1900-01-01 18:00:00    45
1900-01-01 18:15:00    45
1900-01-01 18:30:00    45
1900-01-01 18:45:00    45
1900-01-01 19:00:00    45
1900-01-01 19:15:00    45
1900-01-01 19:30:00    45
1900-01-01 19:45:00    45
1900-01-01 20:00:00    45
1900-01-01 20:15:00    45
1900-01-01 20:30:00    45
1900-01-01 20:45:00    45
1900-01-01 21:00:00    45
1900-01-01 21:15:00    45
1900-01-01 21:30:00    45
1900-01-01 21:45:00    45
1900-01-01 22:00:00    45
1900-01-01 22:15:00    45
1900-01-01 22:30:00    45
1900-01-01 22:45:00    45
1900-01-01 23:00:00    45
1900-01-01 23:15:00    45
1900-01-01 23:30:00    45
1900-01-01 23:45:00    45

[96 rows x 1 columns]

【讨论】:

【参考方案2】:

你可以先以一定的频率取时间戳,然后访问他们的time对数据进行分组:

>>> df.groupby(df.index.floor('15T').time).sum()

          data
00:00:00    30
00:15:00    30
00:30:00    30
00:45:00    30
01:00:00    30
       ...
22:45:00    45
23:00:00    45
23:15:00    45
23:30:00    45
23:45:00    45

[96 rows x 1 columns]

这应该适用于所有其他均分一小时的分钟频率(1、2、3、4、5、6、10、12、15、20、30 或 60 分钟)。

【讨论】:

以上是关于pandas groupby 一天中的时间,带 15 分钟的垃圾箱的主要内容,如果未能解决你的问题,请参考以下文章

在 pandas 中以更快的方式分组一天中的时间

Pandas - Python 2.7:如何将时间序列索引转换为一天中的秒数?

python pandas 按一天中的小时求和

使用 pandas 的滚动窗口计算一天中每个时间的平均值

熊猫方式将一天中的时间(有效的 datetime.time)转换为浮点变量

查找一天中事件的开始时间和结束时间 - Pandas 时间序列 - 这样结束时间不会落入第二天