以下是数据集的示例
日期 | |
---|---|
2020-01-01 01:35 | 50 |
2020-01-01 01:41 | 49 |
2020-01-01 01:46 | 50 |
我发布了5分钟的代码,以便输出与您想要的输出相匹配。将300
更改为900
,持续15分钟。步骤:
-
将
df['Date']
转换为datetime
,这样我们就可以减去两个日期知道他们之间的时差。 -
按日期对
df
进行分组,并为每个组对象调用f
。 -
在
f
中:max-continuous_range
给出最长分段的长度,其中值为50。如果长度为5分钟或更长,则f
返回True。如果f
返回True
,则在列表中追加日期。
使用:
def f(g):
mask = (g['Value'] == 50)
max_continuous_range = (np.max(np.cumsum(g['Date'].where(mask).diff()))
+ timedelta(minutes = 1))
return max_continuous_range.seconds >= 300
df['Date'] = pd.to_datetime(df['Date'])
groups = df.groupby(df['Date'].dt.date, as_index = False)
final_list = [str(idx) for idx, g in groups if f(g)]
输入:
Date Value
0 2020-01-01 01:35 40
1 2020-01-01 01:36 50
2 2020-01-01 01:37 50
3 2020-01-01 01:38 50
4 2020-01-01 01:39 50
5 2020-01-01 01:40 50
6 2020-01-01 01:41 40
7 2020-01-01 01:42 40
输出:
>>> final_list
['2020-01-01']
内部f(g(:
mask
:如果值为50,则为True。
0 False
1 True
2 True
3 True
4 True
5 True
6 False
7 False
df['Date'].where(mask)
将NaT放入掩码不为True的位置。
0 NaT
1 2020-01-01 01:36:00
2 2020-01-01 01:37:00
3 2020-01-01 01:38:00
4 2020-01-01 01:39:00
5 2020-01-01 01:40:00
6 NaT
7 NaT
CCD_ 14给出了两个连续元素之间的差异。如果任何值为NaT,则会给出NaT。df['Date'].where(mask).diff()
:后的结果
0 NaT
1 NaT
2 0 days 00:01:00
3 0 days 00:01:00
4 0 days 00:01:00
5 0 days 00:01:00
6 NaT
7 NaT
现在,连续时间之间的差的累积和将给出所经过的总时间。np.cumsum(...)
:之后
0 NaT
1 NaT
2 0 days 00:01:00
3 0 days 00:02:00
4 0 days 00:03:00
5 0 days 00:04:00
6 NaT
7 NaT
np.max
给出了我们最长的长度。增加1
分钟以处理边界条件
您可以创建一个虚拟变量,该变量本质上充当连续运行的id。它背后的逻辑是将每个值与序列中的下一个值进行比较,看看结果是否不相等。然后,我们将它们强制转换为整数,并进行累积求和。这意味着伪变量只会在条纹结束时增加。然后,我们可以在此伪变量上分组,应用计数,并根据您的条件进行筛选
df['dummy_id'] = (df['Value'] != df['Value'].shift()).cumsum()
grouped_df = df.groupby("dummy_id").agg({"dummy_id": "count", "date": "min"})
然后你所要做的就是根据你想要的东西进行过滤,你应该可以去了。