Панды: Внешнее соединение с указанным диапазоном различий между клавишами - PullRequest
0 голосов
/ 03 января 2019

Я хочу выполнить внешнее объединение для двух фреймов данных, ключами которых являются id: int и date: pd.Timestamp объекты.Кроме того, я хочу, чтобы ключи считались равными, если ids одинаковы (нормальное поведение) и даты либо равны (нормальное поведение), либо разница между датами составляет максимум 30 дней.Затем, когда выполняется внешнее объединение, следует взять date из правого фрейма данных.Ниже приведен пример:

left = pd.DataFrame({"id": [1, 2, 3], "date": [pd.Timestamp(2002, 3, 25), pd.Timestamp(2003, 4, 4), pd.Timestamp(2004, 6, 6)], "val_3": [77, 88, 11]})

right = pd.DataFrame({"id": [1, 2, 3], "date": [pd.Timestamp(2002, 3, 10), pd.Timestamp(2003, 4, 27), pd.Timestamp(2004, 5, 5)], "val_1": [99, 66, 33], "val_2": [101, 102, 103]})

И результат после объединения должен быть:

result = pd.DataFrame({"id": [1, 2, 3, 3], "date": [pd.Timestamp(2002, 3, 10), pd.Timestamp(2003, 4, 27), pd.Timestamp(2004, 6, 6), pd.Timestamp(2004, 5, 5)], "val_3": [77, 88, 11, np.nan], "val_1": [99, 66, np.nan, 33], "val_2": [101, 102, np.nan, 103]})

Ждем ваших ответов!

1 Ответ

0 голосов
/ 03 января 2019

Я думаю merge на 'id' и затем делим DataFrame по необходимости, если дата не попадает в течение 30 дней

import pandas as pd

# Rename so it's easier to split columns later
left = left.rename(columns={'date': 'date_l'})

m = left.merge(right, on='id', how='outer')
mask = m.date >= m.date_l - pd.Timedelta(days=30)

pd.concat([
    m[mask].drop(columns='date_l'),
    m.loc[~mask, left.columns].rename(columns={'date_l': 'date'}),
    m.loc[~mask, right.columns]], 
    ignore_index=True, sort=False)

Вывод:

   id  val_3       date  val_1  val_2
0   1   77.0 2002-03-10   99.0  101.0
1   2   88.0 2003-04-27   66.0  102.0
2   3   11.0 2004-06-06    NaN    NaN
3   3    NaN 2004-05-05   33.0  103.0
...