Разверните pandas диапазоны дат в кадре до отдельных строк. - PullRequest
1 голос
/ 03 февраля 2020

Мне нужно расширить pandas фрейм данных, основанный на дате начала и дате окончания, на отдельные строки.

Исходный фрейм данных такой, как показано ниже

ОРИГИНАЛЬНЫЕ ДАННЫЕ ФРЕЙМЫ

Мой последний фрейм данных должен повторяться для каждого дня между начальной и конечной датой отдельных строк. Результат должен быть расширен для каждой даты, в то время как остальные столбцы, кроме «startdate» и «enddate», сохраняются.

Например, первая строка с startdate = 01-Jan-20 и end-date 15-Jan-20 должна быть расширена до 15 отдельных строк, представляющих одну дату в ряду, как показано в примере результирующего фрейма данных здесь:

ОЖИДАЕМЫЕ РЕЗУЛЬТАТИВНЫЕ ФАЙЛЫ ДАННЫХ

Я пытался с помощью решения itertuples перебирать кадры данных и разбивать диапазоны на отдельные даты, но решение оказывается медленным, когда размер кадра данных велик .

Любое оптимальное решение по этому вопросу высоко ценится.

1 Ответ

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

Используйте pandas.date_range в понимании списка, затем используйте DataFrame.explode (вам нужно использовать как минимум pandas v 0.25.0 для explode метод) :

# Minimal example setup
df = pd.DataFrame({
    'TRIPNAME': ['HIGHSEASON', 'LOWSEASON', 'MEDSEASON'],
    'TRIPCAT': ['H', 'L', 'M'],
    'STARTDATE' : ['01JAN20', '16SEP20', '29JAN20'],
    'ENDDATE': ['15JAN20', '30NOV20', '19JUL20'],
    'FARE': [345, 280, 250]
})


df['DATE'] = [pd.date_range(s, e, freq='d') for s, e in
              zip(pd.to_datetime(df['STARTDATE']), pd.to_datetime(df['ENDDATE']))]

df = df.explode('DATE').drop(['STARTDATE', 'ENDDATE'], axis=1)

print(df)

[out]

      TRIPNAME TRIPCAT  FARE       DATE
0   HIGHSEASON       H   345 2020-01-01
0   HIGHSEASON       H   345 2020-01-02
0   HIGHSEASON       H   345 2020-01-03
0   HIGHSEASON       H   345 2020-01-04
0   HIGHSEASON       H   345 2020-01-05
..         ...     ...   ...        ...
2    MEDSEASON       M   250 2020-07-15
2    MEDSEASON       M   250 2020-07-16
2    MEDSEASON       M   250 2020-07-17
2    MEDSEASON       M   250 2020-07-18
2    MEDSEASON       M   250 2020-07-19
...