фильтр по минимальной разнице двух колонок

Имеется фрейм данных:

data = {'date_id': ['1','1','2','2', '3', '3'],
'date_one': ['1900-01-01 00:08:44','1900-01-01 00:08:59','1900-01-01 00:18:28','1900-01-01 00:18:46', '1900-01-01 00:15:10', '1900-01-01 00:21:36'],
'correct_date': ['1900-01-01 00:08:59','1900-01-01 00:08:59','1900-01-01 00:18:46','1900-01-01 00:18:46', '1900-01-01 00:22:28', '1900-01-01 00:22:28']
}
dates = pd.DataFrame(data, columns = ['date_id','date_one', 'correct_date'])

введите сюда описание изображения

Как я могу оставить только те строки, в которых разница времени в колонках date_one и correct_date по модулю минимальна?

В моем датафрейме колонки с датами уже имеют тип datetime64[ns]

Должен получить вот такой резульат:

введите сюда описание изображения


Ответы (3 шт):

Автор решения: CrazyElf

Ну у меня вот так получилось:

import pandas as pd

data = {'date_id': ['1','1','2','2', '3', '3'],
'date_one': ['1900-01-01 00:08:44','1900-01-01 00:08:59','1900-01-01 00:18:28','1900-01-01 00:18:46', '1900-01-01 00:15:10', '1900-01-01 00:21:36'],
'correct_date': ['1900-01-01 00:08:59','1900-01-01 00:08:59','1900-01-01 00:18:46','1900-01-01 00:18:46', '1900-01-01 00:22:28', '1900-01-01 00:22:28']
}
dates = pd.DataFrame(data)
dates['date_one'] = pd.to_datetime(dates['date_one'], format='%Y-%m-%d')
dates['correct_date'] = pd.to_datetime(dates['correct_date'], format='%Y-%m-%d')
# для сортировки по близости
dates['date_diff'] = dates['correct_date'] - dates['date_one']
dates.sort_values('date_diff').groupby('correct_date').first().reset_index()[['date_id','date_one','correct_date']]

Вывод:

    date_id     date_one    correct_date
0   1   1900-01-01 00:08:59     1900-01-01 00:08:59
1   2   1900-01-01 00:18:46     1900-01-01 00:18:46
2   3   1900-01-01 00:21:36     1900-01-01 00:22:28

Но если ближайшая дата может быть и больше корректной (в приведённых данных она всегда меньше или равна), то надо ещё abs от date_diff будет взять.

→ Ссылка
Автор решения: strawdog

Я не совсем понял критерий отбора минимальных значений, особенно, если таких равноминимальных значений будет несколько. Вероятно, вам подойдет решение от @CrazyElf Но если нужно использовать какой-то порог, то можно решить так:

from datetime import timedelta

res = dates[abs(dates["date_one"]-dates["correct_date"])<timedelta(seconds=15)]

тогда Res будет:

  date_id            date_one        correct_date
1       1 1900-01-01 00:08:59 1900-01-01 00:08:59
3       2 1900-01-01 00:18:46 1900-01-01 00:18:46
→ Ссылка
Автор решения: MaxU

Решение очень похожее на решение @CrazyElf с единственным различием - в результирующем фрейме сохраняются оригинальные значения индекса:

res = (df.loc[df
              .assign(x=(df["date_one"]-df["correct_date"]).abs())
              .sort_values("x")
              .reset_index()
              .groupby("date_id")
              ["index"]
              .first()
       ])

результат:

In [40]: res
Out[40]:
  date_id            date_one        correct_date
1       1 1900-01-01 00:08:59 1900-01-01 00:08:59
3       2 1900-01-01 00:18:46 1900-01-01 00:18:46
5       3 1900-01-01 00:21:36 1900-01-01 00:22:28
→ Ссылка