pandas.merge: совпадение с ближайшей меткой времени> = серия временных меток

У меня есть два кадра данных, оба из которых содержат столбец временной метки с разнесенным интервалом в миллисекундах. Моя цель состоит в том, чтобы сопоставить строки таким образом, чтобы для каждой строки соответствовала: 1) первая метка времени всегда меньше или равна второй временной отметке; 2) согласованные временные метки являются самыми близкими для всех пар временных меток, удовлетворяющих 1).

Есть ли способ сделать это с помощью pandas.merge?

  • Переименование файлов, Python / Jython
  • Обратный для 'index' с аргументами '()' и аргументами ключевого слова '{}' не найден. 0 образцов (-ов):
  • PYTHON - добавление номеров строк на выход
  • Функция для вращения 2d объектов?
  • Автоматически удалять файлы * .pyc и в противном случае - пустые каталоги при проверке новой ветви
  • usecols с parse_dates и именами
  • Ошибка памяти python get_dummies
  • Учитывая список словарей, как я могу устранить дубликаты одного ключа и сортировать по другому
  • 3 Solutions collect form web for “pandas.merge: совпадение с ближайшей меткой времени> = серия временных меток”

    merge() не может выполнить такое соединение, но вы можете использовать searchsorted() :

    Создайте случайные временные метки: t1 , t2 , есть в порядке возрастания:

     import pandas as pd import numpy as np np.random.seed(0) base = np.array(["2013-01-01 00:00:00"], "datetime64[ns]") a = (np.random.rand(30)*1000000*1000).astype(np.int64)*1000000 t1 = base + a t1.sort() b = (np.random.rand(10)*1000000*1000).astype(np.int64)*1000000 t2 = base + b t2.sort() 

    вызовите searchsorted() чтобы найти индекс в t1 для каждого значения в t2 :

     idx = np.searchsorted(t1, t2) - 1 mask = idx >= 0 df = pd.DataFrame({"t1":t1[idx][mask], "t2":t2[mask]}) 

    вот результат:

      t1 t2 0 2013-01-02 06:49:13.287000 2013-01-03 16:29:15.612000 1 2013-01-05 16:33:07.211000 2013-01-05 21:42:30.332000 2 2013-01-07 04:47:24.561000 2013-01-07 04:53:53.948000 3 2013-01-07 14:26:03.376000 2013-01-07 17:01:35.722000 4 2013-01-07 14:26:03.376000 2013-01-07 18:22:13.996000 5 2013-01-07 14:26:03.376000 2013-01-07 18:33:55.497000 6 2013-01-08 02:24:54.113000 2013-01-08 12:23:40.299000 7 2013-01-08 21:39:49.366000 2013-01-09 14:03:53.689000 8 2013-01-11 08:06:36.638000 2013-01-11 13:09:08.078000 

    Чтобы просмотреть этот результат по графику:

     import pylab as pl pl.figure(figsize=(18, 4)) pl.vlines(pd.Series(t1), 0, 1, colors="g", lw=1) pl.vlines(df.t1, 0.3, 0.7, colors="r", lw=2) pl.vlines(df.t2, 0.3, 0.7, colors="b", lw=2) pl.margins(0.02) 

    вывод:

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

    Зеленые линии – t1 , синие линии – t2 , красные линии выбраны из t1 для каждого t2 .

    Я использовал иначе, чем HYRY:

    1. сделать регулярное слияние с внешним соединением (how = 'outer');
    2. сортировать по дате;
    3. используйте fillna (method = 'pad'), чтобы заполнить только нужные столбцы и «pad», если вы хотите взять предыдущую заполненную строку;
    4. отбросьте все строки, которые вам не нужны из внешнего соединения.

    Все это можно записать несколькими строками:

     df=pd.merge(df0, df1, on='Date', how='outer') df=df.sort(['Date'], ascending=[1]) headertofill=list(df1.columns.values) df[headertofill]=df[headertofill].fillna(method='pad') df=df[pd.isnull(df[var_from_df0_only])==False] 

    Вот более простой и более общий метод.

     # data and signal are want we want to merge keys = ['channel', 'timestamp'] # Could be simply ['timestamp'] index = data.loc[keys].set_index(keys).index # Make index from columns to merge on padded = signal.reindex(index, method='pad') # Key step -- reindex with filling joined = data.join(padded, on=keys) # Join to data if needed 
    Python - лучший язык программирования в мире.