Расширить df с диапазоном дат до одной строки в день - PullRequest
0 голосов
/ 10 февраля 2020

У меня есть df, который содержит одну строку на элемент с диапазоном дат, и мне нужно расширить его, чтобы он содержал одну строку в день на элемент.

Это выглядит так:

  from       to         id
1 25/02/2019 27/02/2019 A
2 15/07/2019 16/07/2019 B

И я хочу вот что:

  date       id
1 25/02/2019 A
2 26/07/2019 A
3 27/07/2019 A
4 15/07/2019 B
5 16/07/2019 B

Мне удалось написать код, который работает, но его запуск занимает более часа, поэтому мне интересно, есть ли более эффективный способ сделать это.

Мой код:

df_dates = pd.DataFrame()

for i in range(len(df)):

    start = df.loc[i]['from']
    end = df.loc[i]['to'] + np.timedelta64(1,'D') #includes last day of the range
    dates = np.arange(start, end, dtype='datetime64[D]')

    temp = pd.DataFrame()
    temp = temp.append([df.loc[i]]*len(dates), ignore_index=True)
    temp['datadate'] = dates

    df_dates = df_dates.append(temp, ignore_index=True)

Это займет много времени, потому что реальные диапазоны составляют около 50 лет с более чем 1700 предметами, поэтому новый ДФ огромен, но, возможно, вы знаете хитрость, чтобы сделать так же быстрее :)

Ответы [ 2 ]

2 голосов
/ 10 февраля 2020

Вы можете сначала преобразовать столбцы с датами to_datetime. Затем используйте itertuples и date_range с concat для создания нового расширения DataFrame:

df['from1'] = pd.to_datetime(df['from'])
df['to1'] = pd.to_datetime(df['to'])

L = [pd.Series(r.id, pd.date_range(r.from1, r.to1)) for r in df.itertuples()]
df1 = pd.concat(L).reset_index()
df1.columns = ['date','id']
print (df1)
        date id
0 2019-02-25  A
1 2019-02-26  A
2 2019-02-27  A
3 2019-07-15  B
4 2019-07-16  B
1 голос
/ 10 февраля 2020

Попробуйте:

df['from'] = pd.to_datetime(df['from'])
df['to'] = pd.to_datetime(df['to'])
pd.concat([pd.DataFrame({'date': pd.date_range(row['from'], row['to'], freq='D'), 'id': row['id']})
           for i, row in df.iterrows()], ignore_index=True)
        date id
0 2019-02-25  A
1 2019-02-26  A
2 2019-02-27  A
3 2019-07-15  B
4 2019-07-16  B
...