Python Pandas - Скользящие регрессии для нескольких столбцов в кадре данных - PullRequest
1 голос
/ 17 октября 2019

У меня есть большой фрейм данных, содержащий дневные временные ряды цен для 10 000 столбцов (акций) за период в 20 лет (5000 строк x 10000 столбцов). Отсутствующие наблюдения обозначаются NaN.

            0      1      2      3      4      5       6      7      8      \
31.12.2009  30.75  66.99    NaN    NaN    NaN    NaN  393.87  57.04    NaN   
01.01.2010  30.75  66.99    NaN    NaN    NaN    NaN  393.87  57.04    NaN   
04.01.2010  31.85  66.99    NaN    NaN    NaN    NaN  404.93  57.04    NaN   
05.01.2010  33.26  66.99    NaN    NaN    NaN    NaN  400.00  58.75    NaN   
06.01.2010  33.26  66.99    NaN    NaN    NaN    NaN  400.00  58.75    NaN   

Теперь я хочу запустить скользящую регрессию для окна 250 дней для каждого столбца за весь период выборки и сохранить коэффициент в другом кадре данных

Перебор столбцов и строк с использованием двух циклов for не очень эффективен, поэтому я попробовал это сделать, но получил следующее сообщение об ошибке

def regress(start, end):
    y = df_returns.iloc[start:end].values

    if np.isnan(y).any() == False:
        X = np.arange(len(y))
        X = sm.add_constant(X, has_constant="add")
        model = sm.OLS(y,X).fit()

        return model.params[1]

    else:
        return np.nan


regression_window = 250

for t in (regression_window, len(df_returns.index)):

    df_coef[t] = df_returns.apply(regress(t-regression_window, t), axis=1)
TypeError: ("'float' object is not callable", 'occurred at index 31.12.2009')

1 Ответ

0 голосов
/ 17 октября 2019

вот моя версия, вместо этого используется df.rolling () и выполняется перебор столбцов. Я не совсем уверен, что это то, что вы искали, не стесняйтесь комментировать

import statsmodels.regression.linear_model as sm
import statsmodels.tools.tools as sm2
df_returns =pd.DataFrame({'0':[30,30,31,32,32],'1':[60,60,60,60,60],'2':[np.NaN,np.NaN,np.NaN,np.NaN,np.NaN]})


def regress(X,Z):

    if np.isnan(X).any() == False:
        model = sm.OLS(X,Z).fit()        
        return model.params[1]

    else:
        return np.NaN


regression_window = 3
Z = np.arange(regression_window)
Z= sm2.add_constant(Z, has_constant="add")
df_coef=pd.DataFrame()
for col in df_returns.columns:
    df_coef[col]=df_returns[col].rolling(window=regression_window).apply(lambda col : regress(col, Z))
df_coef
...