Повторение годового цикла с Pandas в Python - PullRequest
1 голос
/ 21 февраля 2020

Я пытаюсь манипулировать годовыми циклами данных в pandas. Я создал годовой цикл (включая високосные дни) данных об осадках, где индекс представляет собой строку, представляющую месяц и день.

Я хотел бы повторить эти данные в течение определенного периода времени (скажем, 1980-2020) с указателем даты и времени. Есть ли хороший способ сделать это в pandas? Единственный способ, которым я могу придумать, - это создать пустой фрейм данных и циклически проходить по годам, проверяя високосные годы, но я уверен, что должен быть лучший способ.

Пока у меня есть:

import pandas as pd
import numpy as np
import calendar

data = np.random.rand(366)
df_annual_cycle = pd.DataFrame(
    columns=['annual_cycle'],
    index=pd.date_range('2004-01-01','2004-12-31').strftime('%m-%d'),
    data=data
)

df_annual_cycle.head()

#        annual_cycle
# 01-01      0.863838
# 01-02      0.234168
# 01-03      0.368678
# 01-04      0.066332
# 01-05      0.493080


df_every_year=pd.DataFrame(
    columns=['rainfall'],index=pd.date_range('1980-01-01','2020-12-31')
)

for year in df_every_year.index.year:
    if calendar.isleap(year):
        df_every_year[
            df_every_year.index.year==year
        ] = df_annual_cycle.values
    elif ~calendar.isleap(year):
        df_every_year[
            df_every_year.index.year==year
        ] = df_annual_cycle.drop(index='02-29').values

Я бы предпочел, в идеале, не преобразовывать в массив numpy, используя .values, так как мой фрейм данных имеет несколько (возможно, изменяемые) столбцы.

1 Ответ

0 голосов
/ 25 февраля 2020

Для всех, кто пытается это сделать, это намного быстрее (хотя и не очень аккуратно):

import pandas as pd
import numpy as np
import calendar

data = np.random.rand(366)
df_annual_cycle = pd.DataFrame(
    columns=['annual_cycle'],
    index=pd.date_range('2004-01-01','2004-12-31').strftime('%m-%d'),
    data=data
)


years=np.arange(1980,2020)
df_every_year=pd.concat([df_annual_cycle]*40)
myindex=(np.repeat(years,366).astype(str)+df_every_year.index)
df_every_year.index=myindex
for year in np.arange(1980,2020):
    if ~calendar.isleap(year):
        df_every_year.drop(index=str(year)+'02-29',inplace=True)
df_every_year.index=pd.to_datetime(df_every_year.index,format='%Y%m-%d')
...