Экстраполировать Pandas DataFrame
Легко интерполировать значения в Pandas.DataFrame
с помощью Series.interpolate
Как можно сделать экстраполяцию?
Например, если указан DataFrame, как показано, как мы можем экстраполировать его еще на 14 месяцев до 2014-12-31? Линейная экстраполяция в порядке.
X1 = range(10)
X2 = map(lambda x: x**2, X1)
df = pd.DataFrame({'x1': X1, 'x2': X2}, index=pd.date_range('20130101',periods=10,freq='M'))
Я думаю, что сначала должен быть создан новый DataFrame, с DateTimeIndex, начиная с 2013-11-31 и продолжая еще 14 M
периоды. Помимо этого я застрял.
1 ответ
Экстраполировать DataFrame
с DatetimeIndex
индекс
Это можно сделать в два этапа:
- Расширить
DatetimeIndex
- Экстраполировать данные
Расширить индекс
затирать df
с новым DataFrame
где данные передискретизируются в новый расширенный индекс на основе начального индекса, периода и частоты. Это позволяет оригиналу df
прийти откуда угодно, как в csv
пример дела. При этом колонки удобно заполняются NaNs!
# Fake DataFrame for example (could come from anywhere)
X1 = range(10)
X2 = map(lambda x: x**2, X1)
df = pd.DataFrame({'x1': X1, 'x2': X2}, index=pd.date_range('20130101',periods=10,freq='M'))
# Number of months to extend
extend = 5
# Extrapolate the index first based on original index
df = pd.DataFrame(
data=df,
index=pd.date_range(
start=df.index[0],
periods=len(df.index) + extend,
freq=df.index.freq
)
)
# Display
print df
x1 x2
2013-01-31 0 0
2013-02-28 1 1
2013-03-31 2 4
2013-04-30 3 9
2013-05-31 4 16
2013-06-30 5 25
2013-07-31 6 36
2013-08-31 7 49
2013-09-30 8 64
2013-10-31 9 81
2013-11-30 NaN NaN
2013-12-31 NaN NaN
2014-01-31 NaN NaN
2014-02-28 NaN NaN
2014-03-31 NaN NaN
Экстраполировать данные
Большинство экстраполяторов требуют, чтобы входные данные были числовыми, а не датами. Это может быть сделано с
# Temporarily remove dates and make index numeric
di = df.index
df = df.reset_index().drop('index', 1)
Смотрите этот ответ о том, как экстраполировать значения каждого столбца DataFrame
с полиномом 3- го порядка.
Фрагмент из ответа
# Curve fit each column for col in fit_df.columns: # Get x & y x = fit_df.index.astype(float).values y = fit_df[col].values # Curve fit column and get curve parameters params = curve_fit(func, x, y, guess) # Store optimized parameters col_params[col] = params[0] # Extrapolate each column for col in df.columns: # Get the index values for NaNs in the column x = df[pd.isnull(df[col])].index.astype(float).values # Extrapolate those points with the fitted function df[col][x] = func(x, *col_params[col])
После того, как столбцы экстраполированы, верните даты
# Put date index back
df.index = di
# Display
print df
x1 x2
2013-01-31 0 0
2013-02-28 1 1
2013-03-31 2 4
2013-04-30 3 9
2013-05-31 4 16
2013-06-30 5 25
2013-07-31 6 36
2013-08-31 7 49
2013-09-30 8 64
2013-10-31 9 81
2013-11-30 10 100
2013-12-31 11 121
2014-01-31 12 144
2014-02-28 13 169
2014-03-31 14 196