#python #pandas #datetimeindex
#python #pandas #datetimeindex
Вопрос:
Я новичок в python, и я борюсь со следующим примером: у меня есть фрейм данных pandas с индексом даты-времени и столбцом с праздниками. Это в ежедневном разрешении.
import pandas as pd
import holidays
hd = holidays.Switzerland(years=[2018])
f = pd.DataFrame(hd.items())
f.columns = ['date', 'feastday']
f['date'] = pd.to_datetime(f['date'])
f = f.set_index('date')
Это выглядит следующим образом:
date feastday
2018-01-01 Neujahrestag
2018-04-01 Ostern
2018-03-30 Karfreitag
2018-04-02 Ostermontag
2018-05-10 Auffahrt
2018-05-20 Pfingsten
2018-05-21 Pfingstmontag
2018-08-01 Nationalfeiertag
2018-12-25 Weihnachten
Теперь я хочу, чтобы данные были не в ежедневном разрешении, а, например, в разрешении 6 часов:
f1 = f.resample('6H').asfreq()
Это работает так, как я хотел, и приводит к:
date feastday
2018-01-01 00:00:00 Neujahrestag
2018-01-01 06:00:00 NaN
2018-01-01 12:00:00 NaN
2018-01-01 18:00:00 NaN
2018-01-02 00:00:00 NaN
2018-01-02 06:00:00 NaN
2018-01-02 12:00:00 NaN
Но теперь я хочу заполнить, например, ‘Neujahrstag’ для всех 2018-01-01, а не только для первого элемента. Результат должен выглядеть следующим образом (не только для ‘Neujahrstag’, но и для всех элементов в фрейме данных mit f). Все элементы с одинаковой датой должны иметь одинаковое значение в feastday. Время на эту дату не имеет значения:
date feastday
2018-01-01 00:00:00 Neujahrestag
2018-01-01 06:00:00 Neujahrestag
2018-01-01 12:00:00 Neujahrestag
2018-01-01 18:00:00 Neujahrestag
2018-01-02 00:00:00 NaN
2018-01-02 06:00:00 NaN
2018-01-02 12:00:00 NaN
Я могу заменить один элемент вручную на:
f1['2018-01-01'] = f1['2018-01-01']['feastday'][0]
Это работает без проблем, но я не запускаю материал автоматически для всех данных… Я попробовал это с помощью цикла for, но у меня не получилось. Кто-нибудь может мне помочь. Может быть, есть и другой (более простой) способ достичь моей цели? Заранее спасибо за вашу помощь.
Марко
Ответ №1:
Группировка по дням с df.groupby(df.index.day)
шаблоном — один из способов сделать это:
f1 = f.resample('6H').asfreq()
res = f1.groupby(f1.index.day).ffill()[['feastday']]
res.head(7)
feastday
date
2018-01-01 00:00:00 Neujahrestag
2018-01-01 06:00:00 Neujahrestag
2018-01-01 12:00:00 Neujahrestag
2018-01-01 18:00:00 Neujahrestag
2018-01-02 00:00:00 NaN
2018-01-02 06:00:00 NaN
2018-01-02 12:00:00 NaN
Комментарии:
1. Спасибо за эту идею, Питер. Мне нужно было только сменить df.index.day на df.index.date, тогда все работает нормально.
Ответ №2:
В этом конкретном случае используйте .ffill
с limit
аргументом, поскольку ваша частота составляет 6 часов, а в сутках 24 часа.
df.resample('6H').ffill(limit=3)
# feastday
#date
#2018-01-01 00:00:00 Neujahrestag
#2018-01-01 06:00:00 Neujahrestag
#2018-01-01 12:00:00 Neujahrestag
#2018-01-01 18:00:00 Neujahrestag
#2018-01-02 00:00:00 NaN
#2018-01-02 06:00:00 NaN
#2018-01-02 12:00:00 NaN
#...
В общем, coud groupby преобразует, если что-то распределяется неравномерно.
df = df.resample('6H').asfreq()
df.groupby(df.index.date).transform('first')
Комментарии:
1. Большое спасибо, это было именно то, что мне было нужно. Работает нормально.