我想绘制一些日期时间,并希望指定一个时间间隔,以便将它们捆绑在一起并制作直方图。因此,例如,如果在一小时的跨度内碰巧有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小时”,以便对日期时间进行某种模运算。这可能吗?
答案 0 :(得分: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'
的索引,并在2天的时段内总计col2
。 pd.Grouper
的行为可能有点令人讨厌,因为在此示例中,垃圾箱在13:49:11 ...处开始和结束...这可能不是您想要的。
pd.cut
+ pd.date_range
如果使用pd.date_range
定义bin,然后使用pd.cut
,则可以更好地控制bin的定义。例如,您可以在此处从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))