pandas - поиск самой последней (но предыдущей) даты во втором базовом фрейме данных - PullRequest
1 голос
/ 16 июня 2020

У меня есть два фрейма данных, и для одного я хочу найти ближайшую (предыдущую) дату в другом.

Если дата совпадает, мне нужно взять предыдущую дату

df_main содержит справочную информацию

Для df_sample я хочу найти Time в df_main для ближайшей (но предыдущей) записи. Я могу сделать это, используя method='ffill', но если дата для поля Time совпадает с днем, когда оно возвращается в этот день - я хочу, чтобы он возвращал предыдущий - в основном <, а не <=.

В моем примере df_res я хочу, чтобы столбец closest_val содержал [ "n/a", 90, 90, 280, 280, 280]

import pandas as pd

dsample = {'Index': [1, 2, 3, 4, 5, 6],
     'Time': ["2020-06-01", "2020-06-02", "2020-06-03", "2020-06-04" ,"2020-06-05" ,"2020-06-06"],
     'Pred': [100, -200, 300, -400 , -500, 600]
    }

dmain = {'Index': [1, 2, 3],
     'Time': ["2020-06-01", "2020-06-03","2020-06-06"],
     'Actual': [90, 280, 650]
    }

def find_closest(x, df2):
    df_res = df2.iloc[df2.index.get_loc(x['Time'], method='ffill')]
    x['closest_time'] = df_res['Time']
    x['closest_val'] = df_res['Actual']
    return x

df_sample = pd.DataFrame(data=dsample)
df_main = pd.DataFrame(data=dmain)

df_sample = df_sample.set_index(pd.DatetimeIndex(df_sample['Time']))
df_main = df_main.set_index(pd.DatetimeIndex(df_main['Time']))
df_res = df_sample.apply(find_closest, df2=df_main ,axis=1)



tables

Ответы [ 2 ]

1 голос
/ 16 июня 2020

Используйте pd.merge_asof (убедитесь, что 'Time' действительно является datetime):

pd.merge_asof(dsample, dmain, left_on="Time", right_on="Time", allow_exact_matches=False)

Результат:

   Index_x       Time  Pred  Index_y  Actual
0        1 2020-06-01   100      NaN     NaN
1        2 2020-06-02  -200      1.0    90.0
2        3 2020-06-03   300      1.0    90.0
3        4 2020-06-04  -400      2.0   280.0
4        5 2020-06-05  -500      2.0   280.0
5        6 2020-06-06   600      2.0   280.0
0 голосов
/ 16 июня 2020

IIU C, мы можем сделать декартово произведение для обоих ваших фреймов данных, затем отфильтровать точные совпадения, а затем применить некоторые logi c, чтобы определить ближайшую дату.

Наконец, мы будем присоединиться к вашим точным и неточным совпадениям в окончательный фрейм данных. future и отбрасывает значения, сохраняя ближайшую дату в прошлом.

df = pd.concat([extact_matches, non_exact_matches], axis=0).sort_values("Time").rename(
    columns={"TimeDelta": "closest_time", "Actual": "closest val"}
)


print(df)

    Index       Time  Pred closest_time  closest val
0       1 2020-06-01   100   2020-06-01           90
3       2 2020-06-02  -200   2020-06-01           90
7       3 2020-06-03   300   2020-06-03          280
10      4 2020-06-04  -400   2020-06-03          280
13      5 2020-06-05  -500   2020-06-03          280
17      6 2020-06-06   600   2020-06-06          650
...