Выберите две или более последовательных строки на основе критерия, используя python - PullRequest
1 голос
/ 27 февраля 2020

У меня есть такой набор данных:

user        time              city    cookie    index
A        2019-01-01 11.00     NYC     123456      1
A        2019-01-01 11.12     CA      234567      2 
A        2019-01-01 11.18     TX      234567      3
B        2019-01-02 12.19     WA      456789      4 
B        2019-01-02 12.21     FL      456789      5
B        2019-01-02 12.31     VT      987654      6
B        2019-01-02 12.50     DC      157890      7
A        2019-01-03 09:12     CA      123456      8
A        2019-01-03 09:27     NYC     345678      9
A        2019-01-03 09:34     TX      123456      10
A        2019-01-04 09:40     CA      234567      11

В этом наборе данных я хочу сравнить и выбрать два или более последовательных , которые соответствуют следующим критериям:

  1. Пользователь должен быть таким же
  2. Разница во времени должна быть менее 15 минут
  3. Повар ie должен отличаться

Так что, если я применю Фильтр I должен получить следующие данные:

user        time              city    cookie    index
A        2019-01-01 11.00     NYC     123456      1
A        2019-01-01 11.12     CA      234567      2 
B        2019-01-02 12.21     FL      456789      5
B        2019-01-02 12.31     VT      987654      6
A        2019-01-03 09:12     CA      123456      8
A        2019-01-03 09:27     NYC     345678      9
A        2019-01-03 09:34     TX      123456      10

Итак, в приведенном выше сравнении первые две строки (индексы 1 и 2) удовлетворяют всем вышеуказанным условиям. Следующие два (индексы 2 и 3) имеют одинаковую готовку ie, индексы 3 и 4 имеют разных пользователей, 5 и 6 выбираются и отображаются, 6 и 7 имеют разницу во времени более 15 минут. 8,9 и 10 соответствуют критериям, а 11 - нет, так как дата с интервалом в 24 часа.

Как я могу решить эту проблему, используя python dataframe? Вся помощь приветствуется.


Что я пробовал:

Я пытался создать флаги с помощью

shift ()

cookiediff=pd.DataFrame(df.Cookie==df.Cookie.shift())
cookiediff.columns=['Cookiediffs']
timediff=pd.DataFrame(pd.to_datetime(df.time) - pd.to_datetime(df.time.shift()))
timediff.columns=['timediff']
mask = df.user != df.user.shift(1)

timediff.timediff[mask] = np.nan
cookiediff['Cookiediffs'][mask] = np.nan

Ответы [ 2 ]

1 голос
/ 28 февраля 2020

Это поможет:

import numpy as np

#you have inconsistent time delim-just to correct it per your sample data
df["time"]=df["time"].str.replace(":", ".")
df["time"]=pd.to_datetime(df["time"], format="%Y-%m-%d %H.%M")

cond_=np.logical_or(
    df["time"].sub(df["time"].shift()).astype('timedelta64[m]').lt(15) &\
    df["user"].eq(df["user"].shift()) &\
    df["cookie"].ne(df["cookie"].shift()), 
    df["time"].sub(df["time"].shift(-1)).astype('timedelta64[m]').lt(15) &\
    df["user"].eq(df["user"].shift(-1)) &\
    df["cookie"].ne(df["cookie"].shift(-1)), 
)

res=df.loc[cond_]

Несколько баллов - вы должны убедиться, что ваш столбец time равен datetime, чтобы условие 15 минут можно было проверить. Затем - конечный фильтр (cond_), который вы получаете, сравнивая каждую строку с предыдущей, проверяя все 3 условия ИЛИ, выполняя то же самое, но проверяя по следующей (в противном случае вы просто получите все последовательные совпадающие строки, кроме первый).

Выходы:

  user                time city  cookie  index
0    A 2019-01-01 11:00:00  NYC  123456      1
1    A 2019-01-01 11:12:00   CA  234567      2
4    B 2019-01-02 12:21:00   FL  456789      5
5    B 2019-01-02 12:31:00   VT  987654      6
7    A 2019-01-03 09:12:00   CA  123456      8
8    A 2019-01-03 09:27:00  NYC  345678      9
9    A 2019-01-03 09:34:00   TX  123456     10
0 голосов
/ 27 февраля 2020

Вы можете использовать регулярные выражения , чтобы изолировать поля и использовать именованные группы, и функцию groupdict(), чтобы сохранить значение каждого поля в словаре и сравнить значения из последний словарь к текущему. Поэтому выполните итерацию по каждой строке набора данных с двумя словарями, текущим словарем и последним словарем, и выполните re.search() для каждой строки со строкой шаблона регулярного выражения, чтобы разделить каждую строку на именованные поля, а затем сравните значение двух словарей .

Итак, что-то вроде:

import re
c_dict=re.search('(?P<user>\w) +(?P<time>\d{4}-\d{2}-\d{2} \d{2}\.\d{2}) +(?P<city>\w+) +(?P<cookie>\d{6}) +(?P<index>\d+)',s).groupdict()

для каждой строки вашего набора данных. Для первой строки вашего набора данных будет создан словарь {'user': 'A', 'time': '2019-01-01 11.00', 'city': 'NYC', 'cookie': '123456', 'index': '1'}. С изолированными полями вы можете легко сравнить значения полей с предыдущими строками, если вы сохранили их в другом словаре.

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