如果日期时间索引的差异小于熊猫系列的 5 分钟,则分组

Posted

技术标签:

【中文标题】如果日期时间索引的差异小于熊猫系列的 5 分钟,则分组【英文标题】:Group if difference of datetime index is less than 5 minutes of a pandas series 【发布时间】:2021-06-20 10:19:25 【问题描述】:

我想执行 pandas 时间序列的 groupby.first(),其中 datetime 索引几乎是连续的,几乎小于 5 分钟的差异。 我看过很多资料,但如果日期时间不是连续的,就像我的例子一样:

ind=['2019-02-28 01:20:00', '2019-02-28 01:21:00','2019-02-28 01:22:00', '2019-02-28 01:23:00',
     '2019-02-28 01:24:00', '2019-02-28 01:25:00','2019-02-28 01:26:00', '2019-02-28 01:27:00',
     '2019-02-28 01:28:00', '2019-02-28 04:05:00','2019-02-28 04:06:00', '2019-02-28 04:07:00',
     '2019-02-28 04:08:00', '2019-02-28 04:09:00','2019-02-28 06:55:00', '2019-02-28 06:56:00',
     '2019-02-28 06:57:00', '2019-02-28 06:58:00','2019-02-28 09:50:00', '2019-02-28 09:51:00',
     '2019-02-28 09:52:00', '2019-02-28 09:53:00','2019-02-28 09:54:00', '2019-02-28 09:55:00',          
     '2019-02-28 09:56:00', '2019-02-28 09:57:00','2019-02-28 09:58:00', '2019-02-28 09:59:00',
     '2019-02-28 10:00:00']

val=[2.11, 2.24, 2.37, 2.42, 2.58, 2.71, 2.76, 3.06, 3.29, 2.04, 2.26,2.55, 2.89, 3.26, 2.2 , 2.54,
     2.85, 3.24, 2.2 , 2.12, 2.11, 2.07,2.1 , 2.16, 2.28, 2.35, 2.44, 2.5 , 2.57]

s = pd.Series(val,index=pd.to_datetime(ind))

我想要的输出应该是:

Datetime               Value
2019-02-28 01:20:00    2.11
2019-02-28 04:05:00    2.04
2019-02-28 06:55:00    2.20
2019-02-28 09:50:00    2.20

谁能帮帮我?

【问题讨论】:

【参考方案1】:

让我们group时差小于5min的连续行块上的数据帧:

df = s.reset_index(name='Value')
b  = df['index'].diff().dt.seconds.gt(300).cumsum()
df = df.groupby(b, as_index=False).first()

说明

重置给定时间序列的索引s,然后计算日期时间索引与前一个元素相比的差异,并使用dt.seconds获得以秒为单位的差异。

>>> df['index'].diff().dt.seconds

0         NaN
1        60.0
2        60.0
3        60.0
4        60.0
5        60.0
6        60.0
7        60.0
8        60.0
9      9420.0
....
25       60.0
26       60.0
27       60.0
28       60.0
Name: index, dtype: float64

现在将总秒数与300 进行比较,以创建一个布尔掩码,后跟cumsum 以识别连续日期时间值之间的差异小于5 min 的行块

>>> df['index'].diff().dt.seconds.gt(300).cumsum()

0     0
1     0
2     0
3     0
4     0
5     0
6     0
7     0
8     0
9     1
...
25    3
26    3
27    3
28    3
Name: index, dtype: int64

Group上述块上的数据帧并使用first聚合

>>> df
                index  Value
0 2019-02-28 01:20:00   2.11
1 2019-02-28 04:05:00   2.04
2 2019-02-28 06:55:00   2.20
3 2019-02-28 09:50:00   2.20

【讨论】:

我很感激【参考方案2】:

使用基于numpy 的解决方案:

from numpy import array, diff, where, split
data = ((s.index.hour*60)+s.index.minute+(s.index.second/60)).astype(int)
data = k:v for k,v in enumerate(data)
result= split(list(data.keys()), where(diff(list(data.values()))>5)[0]+1 )
res = s.iloc[[i[0] for i in result]]

分辨率:

2019-02-28 01:20:00    2.11
2019-02-28 04:05:00    2.04
2019-02-28 06:55:00    2.20
2019-02-28 09:50:00    2.20
dtype: float64

【讨论】:

你介意我在 OP 的问题中将 df 的名称更改为 s,因为它令人困惑,因为 df 通常用于表示 Dataframe,但 OP 用它表示系列。 @ShubhamSharma:继续 :) 我也会在我的回答中更新它 您的解决方案似乎很有趣,我将执行一些基准测试【参考方案3】:

您似乎遗漏了一些值。这会过滤 10**9 纳秒每秒、60 秒每分钟、5 分钟边界的行。

df.loc[df.index.values.astype(int)%(10**9*60*5)==0]

输出

2019-02-28 01:20:00    2.11
2019-02-28 01:25:00    2.71
2019-02-28 04:05:00    2.04
2019-02-28 06:55:00    2.20
2019-02-28 09:50:00    2.20
2019-02-28 09:55:00    2.16
2019-02-28 10:00:00    2.57

【讨论】:

但是例如第一个和第二个观察应该在一起

以上是关于如果日期时间索引的差异小于熊猫系列的 5 分钟,则分组的主要内容,如果未能解决你的问题,请参考以下文章

将索引转换为日期时间对象后,MatplotLib 无法正确绘制熊猫时间序列 1 分钟数据

Hive 中的日期差异小于 15 分钟

如何将日期时间格式转换为分钟 - 熊猫

计算熊猫中2个日期的分钟差[重复]

如何将日期和小时列合并到熊猫系列中的一个索引列中?

熊猫:从日期时间索引合并日期和小时