Как перебрать серию дат для фильтрации по нескольким условиям? - PullRequest
0 голосов
/ 26 июня 2019

Я пытаюсь отфильтровать следующие даты, чтобы получить логическую информацию о том, отслеживается ли данное «окно» данных в течение не менее 30 минут и не более 3 минут между последовательными временными точками В этом окне.Попытка поместить его в цикл for с условием while, но, похоже, не может заставить его работать.Довольно новый для 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 ]

1 голос
/ 27 июня 2019

Вот обобщенный подход Pandas, в котором вы можете указать step и window.Вы можете использовать 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
0 голосов
/ 27 июня 2019

Python 3 поставляется с некоторыми datetime функциями, такими как fromisoformat и total_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('---')
0 голосов
/ 26 июня 2019

Вы можете создать структуру времени / даты / времени с помощью следующих временных меток, а затем выполнить обычные арифметические / условные операции над ними, чтобы получить желаемые результаты.

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

Вы можете масштабировать это до всего вашего фрейма данных, а затем выполнять сравнения по нескольким временным меткам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...