в Python, как вы можете объединить, используя datetime в качестве условия (не точное, но с некоторой разницей во времени)

#python #pandas #dataframe #datetime #merge

#python #pandas #фрейм данных #datetime #слияние

Вопрос:

У меня есть два фрейма данных

 left = pd.DataFrame([['A', 10, datetime(2020, 5, 17, 20, 12, 28)],
                 ['B', 15, datetime(2020, 5, 17, 16, 22, 45)],
                 ['C', 20, datetime(2020, 5, 17, 12, 45, 12)],
                 ['D', 25, datetime(2020, 5, 17, 13, 57, 44)]],
                columns = ['Letter_l', 'Int_l', 'Datetime_l'])
  

и

 right = pd.DataFrame([['A', 20, datetime(2020, 5, 17, 20, 12, 35)],
                  ['B', 30, datetime(2020, 5, 17, 18, 45, 25)],
                  ['C', 40, datetime(2020, 5, 17, 12, 45, 20)],
                  ['D', 50, datetime(2020, 5, 17, 18, 16, 44)]],
                columns = ['Letter_r', 'Int_r', 'Datetime_r'])
  

Я хочу объединить два из трех столбцов: Letter и Datetime .
Для даты и времени я ищу не точное совпадение, а максимальную разницу в 10 секунд для правильного фрейма данных.

Я знаю, как объединяться при нормальных условиях:

 merged_df = pd.merge(left=left, right=right, how='left',
                     left_on=['Letter_l'], right_on=['Letter_r'])
  

но результат, который я ищу, это:

 |-----|--------------|-----------|--------------------|--------------|-----------|--------------------|
|     |   Letter_l   |   Int_l   |     datetime_l     |   Letter_r   |   Int_r   |     datetime_r     | 
|-----|--------------|-----------|--------------------|--------------|-----------|--------------------|
|  0  |      A       |     10    | 2020-05-17 20:12:28|      A       |     20    | 2020-05-17 20:12:35|
|  1  |      C       |     20    | 2020-05-17 12:45:12|      C       |     40    | 2020-05-17 12:45:20|
|-----|--------------|-----------|--------------------|--------------|-----------|--------------------|
  

Можно ли это сделать с помощью стандарта pd.merge ?

Конечно, я мог бы попробовать использовать sqlite3

Ответ №1:

Выполните asof слияние с pd.merge_asof включением DateTime с допуском в 10 секунды:

 df = pd.merge_asof(left.sort_values('Datetime_l'),
                   right.sort_values('Datetime_r'),
                   left_by='Letter_l', right_by='Letter_r',
                   left_on='Datetime_l', right_on='Datetime_r',
                   direction='nearest', tolerance=pd.Timedelta(seconds=10))
       .dropna(subset=['Letter_r'])
  

Результат:

   Letter_l  Int_l          Datetime_l Letter_r  Int_r          Datetime_r
0        C     20 2020-05-17 12:45:12        C   40.0 2020-05-17 12:45:20
3        A     10 2020-05-17 20:12:28        A   20.0 2020-05-17 20:12:35
  

Комментарии:

1. @agustin счастливого кодирования 🙂