Генерировать фрейм данных pandas из серии дат начала и окончания

#python #python-2.7 #datetime #pandas

#python #python-2.7 #дата и время #pandas

Вопрос:

У меня есть список дат начала и окончания, которые я хочу преобразовать в 1 большой фрейм данных.

вот небольшой воспроизводимый пример того, чего я пытаюсь достичь

 import pandas as pd
from pandas.tseries.offsets import *
import datetime as dt

dates = pd.DataFrame([[dt.datetime(2016,01,01),dt.datetime(2016,02,01)], [dt.datetime(2016,01,10), dt.datetime(2016,02,25)], [dt.datetime(2016,02,10), dt.datetime(2016,03,25)]], columns=['start', 'end'])
  

что дает мне даты начала и окончания, такие как:

 In[14]: dates
Out[14]: 
       start        end
0 2016-01-01 2016-02-01
1 2016-01-10 2016-02-25
2 2016-02-10 2016-03-25
  

Я пытаюсь создать фрейм данных с диапазонами дат дней недели на основе этих дат начала / окончания и добавить их вместе.

вот как я решаю проблему, но она не кажется слишком питонической:

 op_series = list()
for row in dates.itertuples():
    time_range = pd.date_range(row.start, row.end, freq=BDay())
    s = len(time_range)
    op_series  = (zip(time_range, [row.start]*s, [row.end]*s))

df = pd.DataFrame(op_series, columns=['date', 'start', 'end'])

In[4]: df.head()
Out[4]: 
        date      start        end
0 2016-01-01 2016-01-01 2016-02-01
1 2016-01-04 2016-01-01 2016-02-01
2 2016-01-05 2016-01-01 2016-02-01
3 2016-01-06 2016-01-01 2016-02-01
4 2016-01-07 2016-01-01 2016-02-01
  

есть ли более эффективный способ, чем создание списка данных и их склеивание?

Спасибо!

Ответ №1:

Все еще немного неуклюже, но, вероятно, более эффективно, чем у вас, поскольку все это в numpy. Объединить фрейм данных с соответствующими различиями в днях

 df = pd.DataFrame([[dt.datetime(2016,1,1),dt.datetime(2016,2,1)], [dt.datetime(2016,1,10), dt.datetime(2016,2,25)], [dt.datetime(2016,2,10), dt.datetime(2016,3,25)]], columns=['start', 'end'])
df['diff'] = (df['end'] - df['start']).dt.days

arr = np.empty(0, dtype=np.uint32)
diff_arr = np.empty(0, dtype=np.uint32)
for value in df['diff'].unique():
    arr = np.append(arr, np.arange(value))
    diff_arr = np.append(diff_arr, np.full(value, value, dtype=np.uint32))
tmp_df = pd.DataFrame(dict(diff=diff_arr, i=arr))
tmp_df['i'] = pd.to_timedelta(tmp_df['i'], unit='D')
df = df.merge(tmp_df, on='diff')
df['date'] = df['start']   df['i']
df.drop(['i', 'diff'], inplace=True, axis=1)
  

Комментарии:

1. 0.00799989700317 во-вторых, для моего метода и 0.0120000839233 для подхода numpy, кусайте медленнее, но, возможно, чем больший диапазон я добавлю, тем эффективнее будет ваш метод