【问题标题】:How to make a histogram of pandas datetimes per specific time interval?如何制作每个特定时间间隔的熊猫日期时间直方图?
【发布时间】:2018-06-19 14:51:07
【问题描述】:

我想绘制一些日期时间,并想指定一个时间间隔,以便将它们捆绑在一起并制作直方图。例如,如果在一小时内碰巧有 n 个日期时间,则将它们组合在一起或将它们解析为年、月、日、小时。并省略分钟和秒。 假设我有一个包含一些日期时间值的数据框:

import pandas as pd
import numpy as np
from datetime import datetime, timedelta

date_today = datetime.now()
days = pd.date_range(date_today, date_today + timedelta(7), freq='D')

np.random.seed(seed=1111)
data = np.random.randint(1, high=100, size=len(days))
df = pd.DataFrame({'test': days, 'col2': data})
df = df.set_index('test')
print(df)

2018-06-19 17:10:32.076646    29
2018-06-20 17:10:32.076646    56
2018-06-21 17:10:32.076646    82
2018-06-22 17:10:32.076646    13
2018-06-23 17:10:32.076646    35
2018-06-24 17:10:32.076646    53
2018-06-25 17:10:32.076646    25
2018-06-26 17:10:32.076646    23

理想情况下,我想指定一个更灵活的时间间隔,例如“6 小时”,以便对日期时间进行某种模运算。这可能吗?

【问题讨论】:

  • 您可以使用pd.cut,然后使用pd.date_range 指定您的垃圾箱,这将允许您指定合理的定期间隔,例如freq='6H'。或者只是pd.Grouper。如果您需要更多帮助,您应该编辑您的问题以包含 MCVE
  • 很抱歉没有提供 MCVE。我希望这有帮助。你提到的方法听起来很有希望。在 pd.cut 或 pd.Grouper 的帮助下,我将如何做到这一点?提前谢谢你。

标签: python pandas python-datetime


【解决方案1】:

pd.Grouper

允许您指定定期的频率间隔,以便对数据进行分组。使用groupby 然后根据这些组聚合您的df。例如,如果 col2 是计数,并且您想将 2 天间隔内的所有计数合并在一起,您可以这样做:

import pandas as pd
df.groupby(pd.Grouper(level=0, freq='2D')).col2.sum()

输出:

test
2018-06-19 13:49:11.560185    85
2018-06-21 13:49:11.560185    95
2018-06-23 13:49:11.560185    88
2018-06-25 13:49:11.560185    48
Name: col2, dtype: int32

您按level=0 分组,即标记为'test' 的索引和col2 在2 天的垃圾箱中的总和。 pd.Grouper 的行为可能有点烦人,因为在此示例中,垃圾箱开始和结束于 13:49:11...,这可能不是您想要的。

pd.cut + pd.date_range

如果您使用pd.date_range 定义垃圾箱,然后使用pd.cut,您可以更好地控制垃圾箱的定义。例如,您可以从 19 日开始每 2 天定义一次垃圾箱。

df.groupby(pd.cut(df.index, 
                  pd.date_range('2018-06-19', '2018-06-27', freq='2D'))).col2.sum()

输出:

(2018-06-19, 2018-06-21]    85
(2018-06-21, 2018-06-23]    95
(2018-06-23, 2018-06-25]    88
(2018-06-25, 2018-06-27]    48
Name: col2, dtype: int32

这很好,因为如果您希望垃圾箱在偶数天开始,您可以在 pd.date_range 中更改开始和结束日期

df.groupby(pd.cut(df.index, 
                  pd.date_range('2018-06-18', '2018-06-28', freq='2D'))).col2.sum()

输出:

(2018-06-18, 2018-06-20]     29
(2018-06-20, 2018-06-22]    138
(2018-06-22, 2018-06-24]     48
(2018-06-24, 2018-06-26]     78
(2018-06-26, 2018-06-28]     23
Name: col2, dtype: int32

如果您真的愿意,可以指定从 2018 年 6 月 19 日凌晨 5 点开始的 2.6 小时垃圾箱:

df.groupby(pd.cut(df.index, 
                  pd.date_range('2018-06-19 5:00:00', '2018-06-28 5:00:00', freq='2.6H'))).col2.sum()
#(2018-06-19 05:00:00, 2018-06-19 07:36:00]     0
#(2018-06-19 07:36:00, 2018-06-19 10:12:00]     0
#(2018-06-19 10:12:00, 2018-06-19 12:48:00]     0
#(2018-06-19 12:48:00, 2018-06-19 15:24:00]    29
#....

直方图。

汇总数据后只需使用.plot(kind='bar')

(df.groupby(pd.cut(df.index, 
                   pd.date_range('2018-06-19', '2018-06-28', freq='2D')))
   .col2.sum().plot(kind='bar', color='firebrick', rot=30))

【讨论】:

  • 这简直太完美了。太感谢了。 pd.Grouper 解决方案非常适合我的用例。
猜你喜欢
  • 2019-07-19
  • 2017-01-12
  • 2017-02-23
  • 2016-07-05
  • 1970-01-01
  • 2020-10-19
  • 1970-01-01
  • 1970-01-01
  • 2015-02-12
相关资源
最近更新 更多