2015-08-19 31 views
5

È pratica comune e utile aggiungere i valori ei residui previsti dall'esecuzione di una regressione su un dataframe come colonne distinte. Sono nuovo di Panda, e ho problemi a eseguire questa operazione molto semplice. So che mi manca qualcosa di ovvio. Ci è stato chiesto a very similar question circa un anno e mezzo fa, ma non è stata data risposta.Aggiunta di valori e residui previsti a dataframe panda

Il dataframe attualmente sembra qualcosa di simile:

y    x1   x2 
880.37   3.17   23 
716.20   4.76   26 
974.79   4.17   73 
322.80   8.70   72 
1054.25   11.45  16 

E tutto quello che ho voglia è quella di restituire un dataframe che ha il valore previsto e residuale da y = x1 + x2 per ogni osservazione:

y    x1   x2  y_hat   res 
880.37   3.17   23  840.27  40.10 
716.20   4.76   26  752.60  -36.40 
974.79   4.17   73  877.49  97.30 
322.80   8.70   72  348.50  -25.70 
1054.25   11.45  16  815.15  239.10 

Ho provato a risolverlo usando statsmodels e panda e non sono stato in grado di risolverlo. Grazie in anticipo!

risposta

5

Ecco una variazione sulla risposta di Alexander che utilizza il modello OLS di statsmodels anziché del modello pandas ols. Possiamo usare la formula o l'interfaccia array/DataFrame per i modelli.

fittedvalues e resid sono serie Panda con l'indice corretto. predict non restituisce una serie di panda.

import numpy as np 
import pandas as pd 
import statsmodels.api as sm 
import statsmodels.formula.api as smf 

df = pd.DataFrame({'x1': [3.17, 4.76, 4.17, 8.70, 11.45], 
        'x2': [23, 26, 73, 72, 16], 
        'y': [880.37, 716.20, 974.79, 322.80, 1054.25]}, 
        index=np.arange(10, 20, 2)) 

result = smf.ols('y ~ x1 + x2', df).fit() 
df['yhat'] = result.fittedvalues 
df['resid'] = result.resid 


result2 = sm.OLS(df['y'], sm.add_constant(df[['x1', 'x2']])).fit() 
df['yhat2'] = result2.fittedvalues 
df['resid2'] = result2.resid 

# predict doesn't return pandas series and no index is available 
df['predicted'] = result.predict(df) 

print(df) 

     x1 x2  y  yhat  resid  yhat2  resid2 \ 
10 3.17 23 880.37 923.949309 -43.579309 923.949309 -43.579309 
12 4.76 26 716.20 890.732201 -174.532201 890.732201 -174.532201 
14 4.17 73 974.79 656.155079 318.634921 656.155079 318.634921 
16 8.70 72 322.80 610.510952 -287.710952 610.510952 -287.710952 
18 11.45 16 1054.25 867.062458 187.187542 867.062458 187.187542 

    predicted 
10 923.949309 
12 890.732201 
14 656.155079 
16 610.510952 
18 867.062458 

Come anteprima, v'è un metodo di previsione esteso nei risultati del modello in statsmodels master (0,7), ma l'API non è ancora risolta:

>>> print(result.get_prediction().summary_frame()) 
      mean  mean_se mean_ci_lower mean_ci_upper obs_ci_lower \ 
10 923.949309 268.931939 -233.171432 2081.070051 -991.466820 
12 890.732201 211.945165  -21.194241 1802.658643 -887.328646 
14 656.155079 269.136102 -501.844105 1814.154263 -1259.791854 
16 610.510952 282.182030 -603.620329 1824.642233 -1339.874985 
18 867.062458 329.017262 -548.584564 2282.709481 -1214.750941 

    obs_ci_upper 
10 2839.365439 
12 2668.793048 
14 2572.102012 
16 2560.896890 
18 2948.875858 
+0

Grazie, questo è stato un grande aiuto! –

1

Quindi, è educato formulare le domande in modo che sia facile per i contributori eseguire il codice.

import pandas as pd 

y_col = [880.37, 716.20, 974.79, 322.80, 1054.25] 
x1_col = [3.17, 4.76, 4.17, 8.70, 11.45] 
x2_col = [23, 26, 73, 72, 16] 

df = pd.DataFrame() 
df['y'] = y_col 
df['x1'] = x1_col 
df['x2'] = x2_col 

quindi chiamando df.head() rendimenti:

  y  x1 x2 
0 880.37 3.17 23 
1 716.20 4.76 26 
2 974.79 4.17 73 
3 322.80 8.70 72 
4 1054.25 11.45 16 

Ora per la tua domanda, è abbastanza semplice per aggiungere colonne con valori calcolati, se non sto accordo con i dati di esempio:

df['y_hat'] = df['x1'] + df['x2'] 
df['res'] = df['y'] - df['y_hat'] 

Per me, questi frutti:

  y  x1 x2 y_hat  res 
0 880.37 3.17 23 26.17 854.20 
1 716.20 4.76 26 30.76 685.44 
2 974.79 4.17 73 77.17 897.62 
3 322.80 8.70 72 80.70 242.10 
4 1054.25 11.45 16 27.45 1026.80 

Spero che questo aiuti!

+1

Per aggiungere le colonne che sono combinazioni aritmetiche di esistere colonne puoi anche fare 'df.eval ('y_hat = x1 + y1')' che è bello, specialmente se il tuo nome DataFrame è lungo – JoeCondron

+0

Molto utile. Assicurati di aggiungere il codice sorgente del dataframe in futuro. Grazie! –

1

Questo dovrebbe essere auto esplicativo.

import pandas as pd 

df = pd.DataFrame({'x1': [3.17, 4.76, 4.17, 8.70, 11.45], 
        'x2': [23, 26, 73, 72, 16], 
        'y': [880.37, 716.20, 974.79, 322.80, 1054.25]}) 
model = pd.ols(y=df.y, x=df.loc[:, ['x1', 'x2']]) 
df['y_hat'] = model.y_fitted 
df['res'] = model.resid 

>>> df 
     x1 x2  y  y_hat   res 
0 3.17 23 880.37 923.949309 -43.579309 
1 4.76 26 716.20 890.732201 -174.532201 
2 4.17 73 974.79 656.155079 318.634921 
3 8.70 72 322.80 610.510952 -287.710952 
4 11.45 16 1054.25 867.062458 187.187542 
+0

Questo era semplice e migliore. –