如何遍历一系列日期以基于多个条件进行过滤?

时间:2019-06-26 19:23:45

标签: python pandas datetime

我正在尝试过滤以下日期,以返回逻辑,该逻辑是否跟踪持续时间至少30分钟且在该窗口内连续时间点之间不超过3分钟的给定“窗口”。尝试将其放入带有while条件的for循环中,但似乎无法使其正常工作。对于python来说是相当新的,任何帮助都值得赞赏。条件列是我想要的输出。由于没有报告至少30分钟的时间戳序列,并且连续时间戳之间的差异小于3分钟,因此所有结果均为假,而跟踪的最后一位时间戳大于30分钟,并且连续时间戳之间的差异较小超过3分钟。

      date                    condition
0     2019-04-11 11:10:00     False
1     2019-04-11 11:10:00     False
2     2019-04-11 11:11:00     False
3     2019-04-11 11:11:00     False
4     2019-04-11 11:11:00     False
5     2019-04-11 11:11:00     False
6     2019-04-11 11:11:00     False
7     2019-04-16 19:05:00     False
8     2019-04-16 19:05:00     False
9     2019-04-16 19:05:00     False
10    2019-04-16 19:05:00     False
11    2019-04-16 19:24:00     False
12    2019-04-16 19:25:00     False
13    2019-04-16 19:25:00     False
14    2019-04-16 19:25:00     False
15    2019-04-16 19:25:00     False
16    2019-04-16 19:25:00     False
17    2019-04-16 19:25:00     False
18    2019-04-16 19:25:00     False
19    2019-04-16 19:25:00     False
20    2019-04-16 19:25:00     False
21    2019-04-16 19:26:00     False
22    2019-04-16 19:26:00     False
23    2019-04-16 19:26:00     False
24    2019-04-16 19:26:00     False
25    2019-04-16 19:26:00     False
26    2019-04-16 19:26:00     False
27    2019-04-16 19:26:00     False
28    2019-04-16 19:26:00     False
29    2019-04-16 19:26:00     False
38533   2019-04-28 09:42:00    True
38534   2019-04-28 09:42:00    True
38535   2019-04-28 09:43:00    True
38536   2019-04-28 09:44:00    True
38537   2019-04-28 09:45:00    True
38538   2019-04-28 09:46:00    True
38539   2019-04-28 09:47:00    True
38540   2019-04-28 09:47:00    True
38541   2019-04-28 09:48:00    True
38542   2019-04-28 09:49:00    True
38543   2019-04-28 09:50:00    True
38544   2019-04-28 09:51:00    True
38545   2019-04-28 09:52:00    True
38546   2019-04-28 09:53:00    True
38547   2019-04-28 09:54:00    True
38548   2019-04-28 09:55:00    True
38549   2019-04-28 09:56:00    True
38550   2019-04-28 09:57:00    True
38551   2019-04-28 09:57:00    True
38552   2019-04-28 09:58:00    True
38553   2019-04-28 09:59:00    True
38554   2019-04-28 10:00:00    True
38555   2019-04-28 10:01:00    True
38556   2019-04-28 10:02:00    True
38557   2019-04-28 10:02:00    True
38558   2019-04-28 10:03:00    True
38559   2019-04-28 10:04:00    True
38560   2019-04-28 10:05:00    True
38561   2019-04-28 10:06:00    True
38562   2019-04-28 10:07:00    True
38563   2019-04-28 10:07:00    True
38564   2019-04-28 10:08:00    True
38565   2019-04-28 10:09:00    True
38566   2019-04-28 10:10:00    True
38567   2019-04-28 10:11:00    True
38568   2019-04-28 10:12:00    True
38569   2019-04-28 10:13:00    True
38570   2019-04-28 10:14:00    True
38571   2019-04-28 10:14:00    True
38572   2019-04-28 10:15:00    True
38573   2019-04-28 10:15:00    True

3 个答案:

答案 0 :(得分:1)

这是一种通用的Pandas方法,您可以在其中指定stepwindow。您可以使用diff()来确定连续时间戳之间的差异超过指定的step(在这种情况下为3分钟)的行,然后使用cumcount()来标识单独的组,最后使用transform()创建您的condition列,以检查每个相应的组是否至少包含您的window(在这种情况下为30个时间戳):

step = 3
window = 30
df['date'] = pd.to_datetime(df['date'], format='%Y-%m-%d %H:%M:%S')

df['condition'] = (df['date'].diff().astype('timedelta64[m]')<=step)
index = df[df['condition']].index
df['condition'] = df.groupby('condition').cumcount()
df[df.index.isin(index)] = np.nan
df = df.ffill()
df['condition'] = df.groupby('condition').transform('count')>=window

输出:

                  date  condition
0  2019-04-11 11:10:00      False
1  2019-04-11 11:10:00      False
2  2019-04-11 11:10:00      False
3  2019-04-11 11:10:00      False
4  2019-04-11 11:10:00      False
5  2019-04-11 11:10:00      False
6  2019-04-11 11:10:00      False
7  2019-04-16 19:05:00      False
8  2019-04-16 19:05:00      False
9  2019-04-16 19:05:00      False
10 2019-04-16 19:05:00      False
11 2019-04-16 19:24:00      False
12 2019-04-16 19:24:00      False
13 2019-04-16 19:24:00      False
14 2019-04-16 19:24:00      False
15 2019-04-16 19:24:00      False
16 2019-04-16 19:24:00      False
17 2019-04-16 19:24:00      False
18 2019-04-16 19:24:00      False
19 2019-04-16 19:24:00      False
20 2019-04-16 19:24:00      False
21 2019-04-16 19:24:00      False
22 2019-04-16 19:24:00      False
23 2019-04-16 19:24:00      False
24 2019-04-16 19:24:00      False
25 2019-04-16 19:24:00      False
26 2019-04-16 19:24:00      False
27 2019-04-16 19:24:00      False
28 2019-04-16 19:24:00      False
29 2019-04-16 19:24:00      False
30 2019-04-28 09:42:00       True
31 2019-04-28 09:42:00       True
32 2019-04-28 09:42:00       True
33 2019-04-28 09:42:00       True
34 2019-04-28 09:42:00       True
35 2019-04-28 09:42:00       True
36 2019-04-28 09:42:00       True
37 2019-04-28 09:42:00       True
38 2019-04-28 09:42:00       True
39 2019-04-28 09:42:00       True
40 2019-04-28 09:42:00       True
41 2019-04-28 09:42:00       True
42 2019-04-28 09:42:00       True
43 2019-04-28 09:42:00       True
44 2019-04-28 09:42:00       True
45 2019-04-28 09:42:00       True
46 2019-04-28 09:42:00       True
47 2019-04-28 09:42:00       True
48 2019-04-28 09:42:00       True
49 2019-04-28 09:42:00       True
50 2019-04-28 09:42:00       True
51 2019-04-28 09:42:00       True
52 2019-04-28 09:42:00       True
53 2019-04-28 09:42:00       True
54 2019-04-28 09:42:00       True
55 2019-04-28 09:42:00       True
56 2019-04-28 09:42:00       True
57 2019-04-28 09:42:00       True
58 2019-04-28 09:42:00       True
59 2019-04-28 09:42:00       True
60 2019-04-28 09:42:00       True
61 2019-04-28 09:42:00       True
62 2019-04-28 09:42:00       True
63 2019-04-28 09:42:00       True
64 2019-04-28 09:42:00       True
65 2019-04-28 09:42:00       True
66 2019-04-28 09:42:00       True
67 2019-04-28 09:42:00       True
68 2019-04-28 09:42:00       True
69 2019-04-28 09:42:00       True
70 2019-04-28 09:42:00       True

答案 1 :(得分:0)

您可以通过以下时间戳创建一个时间/日期时间结构,然后对这些时间戳进行常规的算术/条件运算以获得所需的结果。

import time

Tstamp_str = "2019-04-11 11:10:00"

Tstamp_obj = time.strptime(Tstamp_str, "%Y-%m-%d %H:%M:%S")

以上代码的作用是根据给定的字符串创建一个时间结构。现在,我们可以进一步使用上述时间结构的属性进行比较。幕后发生的事情是,我们创建了一个具有不同变量的结构,并为这些变量提供了字符串中的值。因此,如果您这样做:-

print(Tstamp_obj)

输出:-

time.struct_time(tm_year=2019, tm_mon=4, tm_mday=11, tm_hour=11, tm_min=10, tm_sec=0, tm_wday=3, tm_yday=101, tm_isdst=-1)

您可以进一步使用此结构/对象的属性进行比较。

示例:-

如果要测试小时数是否大于6。

print(Tstamp_obj.tm_hour > 6)

输出:-

True

您可以将其缩放到整个数据帧,然后在几个时间戳上进行比较。

答案 2 :(得分:0)

Python 3附带了一些datetime函数,例如fromisoformattotal_seconds,以使其变得更容易。如果您以大字符串形式阅读输入内容,则可以从以下所有内容中提取时间对象并使其成为时间对象:

from datetime import datetime

# Extract the timestamps from the big string.  Return a
# list of datetime objects.
def extract_times(times_data_string):
    times = []
    for line in times_data_string.strip().split('\n'):
        date_string = line.split('  ')[-1].strip()
        t = datetime.fromisoformat(date_string)
        times.append(t)
    return times

如果您要查找连续时间间隔不超过30秒但总间隔至少为30分钟(1800秒)的时间范围,则可以执行以下操作。虽然我不知道这是否行得通,因为您的数据没有有效的示例。大概我在这里做的是1)从第一次开始,2)继续查看紧随其后的时间戳,直到找到间隔大于30秒的连续对,3)查看最后一次间隔是否至少是30分钟后开始时间,4)在原始数据中使用第二个时间戳重复该过程。

有更快的方法可以做到这一点(例如,我们可以先计算连续时间之间的所有差异,这样我们就不必一遍又一遍地进行相同的计算,然后查看没有差异的子序列大于30秒,但从开始到结束至少相差1800秒)。希望这会给您一个想法。

times = extract_times(time_info)

for i in times:
    start_time = i
    end_time = start_time
    for j in times:
        thirty_sec_test = ((j - end_time).total_seconds() <= 30.0)
        if thirty_sec_test:
            end_time = j
        else:
            break
    if (j - i).total_seconds() >= 1800:
        print("Valid block of time between these two:")
        print(start_time)
        print(end_time)
        print('---')