如果日期时间索引的差异小于 pandas 系列的 5 分钟,则分组
Group if difference of datetime index is less than 5 minutes of a pandas series
我想执行 groupby.first() 的 pandas 时间序列,其中日期时间索引几乎是连续的,几乎相差不到 5 分钟。
我见过很多 material 但如果日期时间不是像我的示例那样连续的话,我从来没有见过:
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
谁能帮帮我?
使用基于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
您似乎遗漏了一些值。这会在一秒内过滤 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
让我们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
[=23 的行块=]
>>> 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
我想执行 groupby.first() 的 pandas 时间序列,其中日期时间索引几乎是连续的,几乎相差不到 5 分钟。 我见过很多 material 但如果日期时间不是像我的示例那样连续的话,我从来没有见过:
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
谁能帮帮我?
使用基于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
您似乎遗漏了一些值。这会在一秒内过滤 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
让我们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
[=23 的行块=]
>>> 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