Переход от среднемесячных данных к интерполированным дневным временным рядам - PullRequest
0 голосов
/ 18 марта 2020

Меня интересует получение среднемесячных значений для каждого месяца и установка среднемесячных значений равными значению на 15-й день каждого месяца (в пределах дневной серии).

Я начинаю с следующие (это среднемесячные значения, которые мне даны):

m_avg = pd.DataFrame({'Month': ['1.527013956', '1.899169054', '1.669356146','1.44920871', '1.188557788', '1.017035727', '0.950243755', '1.022453993', '1.203913739', '1.369545041','1.441827406','1.48621651']

РЕДАКТИРОВАТЬ: я добавил еще одно значение в кадр данных, чтобы теперь было 12 значений.

Далее я хочу поместить каждое из этих месячных значений на 15-й день (в пределах каждого месяца) для следующего периода времени:

ts = pd.date_range(start='1/1/1950', end='12/31/1999', freq='D')

Я знаю, как вытащить дату на 15-й день уже существующие ежедневные ряды, используя:

df= df.loc[(df.index.day==15)] # Where df is any daily timeseries

Наконец, я знаю, как интерполировать значения, если у меня есть среднемесячные значения на 15-й день каждого месяца, используя:

df.loc[:, ['Col1']] = df.loc[:, ['Col1']].interpolate(method='linear', limit_direction='both', limit=100)

Как мне перейти от месячного DataFrame к интерполированному ежедневному DataFrame, где я линейно интерполирую между 15-м днем ​​каждого месяца, который является месячным значением моего исходного DataFrame по построению?

РЕДАКТИРОВАТЬ:

Ваше предложение использовать np.tile () было хорошо, но мне пришлось сделать это для нескольких столбцов. Вместо np.tile я использовал:

index = pd.date_range(start='1/1/1950', end='12/31/1999', freq='MS')
m_avg = pd.concat([month]*49,axis=0).set_index(index)

Возможно, есть лучшее решение, но пока это работает для моих нужд.

1 Ответ

1 голос
/ 19 марта 2020

Вот один из способов сделать это:

import pandas as pd
import numpy as np

# monthly averages, note these should be cast to float 
month = np.array(['1.527013956', '1.899169054', '1.669356146', 
                  '1.44920871',  '1.188557788', '1.017035727',
                  '0.950243755', '1.022453993', '1.203913739', 
                  '1.369545041', '1.441827406', '1.48621651'], dtype='float')

# expand this to 51 years, with the same monthly averages repeating each year
# (obviously not very efficient, probably there are better ways to attack the problem, 
# but this was the question)
month = np.tile(month, 51)

# create DataFrame with these values
m_avg = pd.DataFrame({'Month': month})

# set the date index to the desired time period
m_avg.index = pd.date_range(start='1/1/1950', end='12/1/2000', freq='MS')

# shift the index by 14 days to get the 15th of each month
m_avg = m_avg.tshift(14, freq='D')

# expand the index to daily frequency
daily = m_avg.asfreq(freq='D')

# interpolate (linearly) the missing values
daily = daily.interpolate()

# show result
display(daily)

Вывод:

            Month
1950-01-15  1.527014
1950-01-16  1.539019
1950-01-17  1.551024
1950-01-18  1.563029
1950-01-19  1.575034
...         ...
2000-12-11  1.480298
2000-12-12  1.481778
2000-12-13  1.483257
2000-12-14  1.484737
2000-12-15  1.486217

18598 rows × 1 columns
...