Как преобразовать dataframe?

У меня есть датафрейм:

df1 = pd.DataFrame([['2011-01-01','2011-01-03','A'], ['2011-04-01','2011-04-01','A'], ['2012-08-28','2012-08-30','B'], ['2015-04-03','2015-04-05','A'], ['2015-08-21','2015-08-21','B']], columns = ['d0', 'd1', 'event'])


d0  d1  event
0   2011-01-01  2011-01-03  A
1   2011-04-01  2011-04-01  A
2   2012-08-28  2012-08-30  B
3   2015-04-03  2015-04-05  A
4   2015-08-21  2015-08-21  B

Т.е. это некоторые события А и В (событий на самом деле больше, располагаются они вперемешку, но пересечения по датам у них нет), которые происходили в указанный промежуток от d0 до d1. Причем, этот промежуток может составлять 1 день (d0=d1). Мне нужно перейти от df1 к df2, в котором эти промежутки времени "развернуты" для каждого события, т.е.:

df2 = pd.DataFrame([['2011-01-01','A'], ['2011-01-02','A'], ['2011-01-03','A'], ['2011-04-01','A'], ['2012-08-28','B'], ['2012-08-29','B'], ['2012-08-30','B'], ['2015-04-03','A'], ['2015-04-04','A'], ['2015-04-05','A'], ['2015-08-21','В']], columns = ['Date', 'event'])

    Date    event
0   2011-01-01  A
1   2011-01-02  A
2   2011-01-03  A
3   2011-04-01  A
4   2012-08-28  B
5   2012-08-29  B
6   2012-08-30  B
7   2015-04-03  A
8   2015-04-04  A
9   2015-04-05  A
10  2015-08-21  В

Как можно сделать это наиболее просто?


Ответы (1 шт):

Автор решения: strawdog

При исходных:

import pandas as pd

df1 = pd.DataFrame([['2011-01-01','2011-01-03','A'], ['2012-08-28','2012-08-30','B'], ['2015-04-03','2015-04-05','A']], columns = ['d0', 'd1', 'event'])
df2 = pd.DataFrame(['2011-01-01', '2011-01-02', '2011-01-03', '2012-08-28', '2012-08-29', '2012-08-30', '2015-04-03', '2015-04-04', '2015-04-05'], columns = ['Date'])

можно сделать так:

df1['d0'] = pd.to_datetime(df1['d0'])
df1['d1'] = pd.to_datetime(df1['d1'])
df2['Date'] = pd.to_datetime(df2['Date'])

tmp = pd.melt(df1, id_vars='event', value_vars=['d0', 'd1']).set_index('value').sort_index().resample("1D").ffill().reset_index()
res = df2.merge(tmp, left_on="Date", right_on="value")

тогда res получится:

        Date      value event variable
0 2011-01-01 2011-01-01     A       d0
1 2011-01-02 2011-01-02     A       d0
2 2011-01-03 2011-01-03     A       d1
3 2012-08-28 2012-08-28     B       d0
4 2012-08-29 2012-08-29     B       d0
5 2012-08-30 2012-08-30     B       d1
6 2015-04-03 2015-04-03     A       d0
7 2015-04-04 2015-04-04     A       d0
8 2015-04-05 2015-04-05     A       d1

Дальше, думаю, сами оставите нужные колонки.

→ Ссылка