Получить записи, которые находятся на интервале времени от заданной даты и определенных условий в фрейме данных pandas

Пусть это будет следующий Python Panda DataFrame:

|   ID      |    date                 |  direction    | country_ID |
|-----------|-------------------------|---------------|------------|
|   0       |    2022-04-01 10:00:01  |    IN         |    UK      |
| unknown   |    2022-04-01 10:00:03  |    IN         |    UK      |
|   0       |    2022-04-01 12:00:01  |    OUT        |    UK      |
|   0       |    2022-04-01 12:30:11  |    IN         |    GER     |
|   1       |    2022-04-01 10:00:00  |    IN         |    GER     |
|   1       |    2022-04-01 08:04:03  |    OUT        |    GER     |
| unknown   |    2022-04-01 10:20:02  |    OUT        |    USA     |
| unknown   |    2022-04-01 09:59:58  |    IN         |    GER     |
| unknown   |    2022-04-01 05:04:03  |    OUT        |    ITL     |
| unknown   |    2022-04-01 05:04:01  |    OUT        |    ITL     |
|   2       |    2022-04-01 05:03:59  |    OUT        |    ITL     |

Мне нужно создать DataFrame, содержащий строки с неизвестным значением идентификатора, которые имеют совпадающую запись со значениями направления и страны_ID с интервалом в 2 секунды (его можно изменить), но идентификатор строки, которой он соответствует, отличается от неизвестного.

Все строки неизвестны:

|   ID      |    date                 |  direction    | country_ID |
|-----------|-------------------------|---------------|------------|
| unknown   |    2022-04-01 10:00:03  |    IN         |    UK      |
| unknown   |    2022-04-01 10:20:02  |    OUT        |    USA     |
| unknown   |    2022-04-01 09:59:58  |    IN         |    GER     |
| unknown   |    2022-04-01 05:04:03  |    OUT        |    ITL     |
| unknown   |    2022-04-01 05:04:01  |    OUT        |    ITL     |

Примеры соответствия для каждой строки, указанной выше:

|   ID      |    date                 |  direction    | country_ID |
|-----------|-------------------------|---------------|------------|
| unknown   |    2022-04-01 10:00:03  |    IN         |    UK      |
|   0       |    2022-04-01 10:00:01  |    IN         |    UK      |
|   ID      |    date                 |  direction    | country_ID |
|-----------|-------------------------|---------------|------------|
| unknown   |    2022-04-01 10:20:02  |    OUT        |    USA     |
|   ID      |    date                 |  direction    | country_ID |
|-----------|-------------------------|---------------|------------|
| unknown   |    2022-04-01 09:59:59  |    IN         |    GER     |
|   1       |    2022-04-01 10:00:00  |    IN         |    GER     |
|   ID      |    date                 |  direction    | country_ID |
|-----------|-------------------------|---------------|------------|
| unknown   |    2022-04-01 05:04:03  |    OUT        |    ITL     |
|   ID      |    date                 |  direction    | country_ID |
|-----------|-------------------------|---------------|------------|
| unknown   |    2022-04-01 05:04:01  |    OUT        |    ITL     |
| 2         |    2022-04-01 05:03:59  |    OUT        |    ITL     |

Удаляем те, у которых нет совпадений. Получаем результирующий DataFrame:

|   ID      |    date                 |  direction    | country_ID |  date_match          |   ID_match    |
|-----------|-------------------------|---------------|------------|----------------------|---------------|
| unknown   |    2022-04-01 10:00:03  |    IN         |    UK      |  2022-04-01 10:00:01 |    0          |
| unknown   |    2022-04-01 09:59:58  |    IN         |    GER     |  2022-04-01 10:00:00 |    1          |
| unknown   |    2022-04-01 05:04:01  |    OUT        |    ITL     |  2022-04-01 05:03:59 |    2          |

Спасибо заранее за вашу помощь.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
23
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать маску, чтобы разделить фрейм данных на две части, и pandas.merge_asof, чтобы найти совпадения по группам и в течение 2 секунд:

df['date'] = pd.to_datetime(df['date'])

mask = df['ID'].eq('unknown')

idx = (pd
 .merge_asof(df[mask].sort_values(by='date').reset_index(),
             df[~mask].sort_values(by='date'),
             by=['direction', 'country_ID'],
             on='date',
             direction='nearest', tolerance=pd.Timedelta('2s'),
             )
 .loc[lambda d: d['ID_y'].notna(), 'index']
)

df.loc[sorted(idx)]

выход:

        ID                date direction country_ID
1  unknown 2022-04-01 10:00:03        IN         UK
7  unknown 2022-04-01 09:59:58        IN        GER
9  unknown 2022-04-01 05:04:01       OUT        ITL
с объединенными данными
df2 = (pd
 .merge_asof(df[mask].sort_values(by='date').reset_index(),
             df[~mask].sort_values(by='date').rename(columns = {'date': 'date_match'}),
             by=['direction', 'country_ID'],
             left_on='date', right_on='date_match',
             direction='nearest', tolerance=pd.Timedelta('2s'),
             suffixes=('', '_match')
             )
 .loc[lambda d: d['ID_match'].notna()]
 .set_index('index').sort_index()

)

выход:

            ID                date direction country_ID ID_match          date_match
index                                                                               
1      unknown 2022-04-01 10:00:03        IN         UK        0 2022-04-01 10:00:01
7      unknown 2022-04-01 09:59:58        IN        GER        1 2022-04-01 10:00:00
9      unknown 2022-04-01 05:04:01       OUT        ITL        2 2022-04-01 05:03:59

Как я могу добавить указанную выше информацию о совпадении в полученный DataFrame? Извините, я редактировал пост как раз в тот момент, когда вы ответили :(

Carola 06.05.2022 16:14

см. обновление для данных матча

mozway 06.05.2022 16:17

Другие вопросы по теме