Короткий ответ
merge_asof нужен, когда у двух таблиц нет точного совпадения по времени, но логически нужно сопоставить событие с ближайшим по времени (обычно предыдущим) значением из другой таблицы, например событие продажи с последней известной на тот момент ценой или курсом валюты.
Как это работает подробнее
merge_asof сортирует обе таблицы по ключу (обычно временному) и для каждой строки левой таблицы находит последнюю строку правой таблицы, чья временная метка не превышает временную метку левой строки (direction='backward' по умолчанию); обычный merge по равенству требует точного совпадения значений ключа и не умеет искать "ближайшее подходящее".
Пример кода
Пример на Python
import pandas as pd
trades = pd.DataFrame({'time': pd.to_datetime(['2024-01-01 10:05', '2024-01-01 10:20']), 'amount': [100, 200]})
rates = pd.DataFrame({'time': pd.to_datetime(['2024-01-01 10:00', '2024-01-01 10:15']), 'rate': [90.0, 91.5]})
merged = pd.merge_asof(trades, rates, on='time', direction='backward')
print(merged)Что использовать на практике
- На практике. типичный пример — сопоставить время транзакции с действовавшим на этот момент тарифом или курсом обмена, который меняется не в момент каждой транзакции, а периодически; перед использованием обе таблицы обязательно должны быть отсортированы по ключу объединения, иначе результат будет неверным или функция выбросит ошибку.
- Проверка. для сделки в 10:05 должен применяться курс 90.0 (действовавший с 10:00), а для сделки в 10:20 — курс 91.5 (действовавший с 10:15), что соответствует принципу "последнее известное значение на момент события".
Подводные камни
- Частые ошибки. пытаются решить задачу обычным merge с последующей сложной постобработкой вместо использования готового merge_asof, усложняя код и рискуя ошибиться в логике "последнего известного значения"; забывают про направление (direction) и получают сопоставление с будущим значением тарифа вместо действовавшего на момент события, если по смыслу нужно backward, а не forward или nearest.