2015-08-19 63 views
5

将预测值和残差作为不同的列附加到数据框上,这是一种有用且常见的做法。我是熊猫新手,在执行这个非常简单的操作时遇到了问题。我知道我错过了一些明显的东西。在一年半前被问到了a very similar question,但没有真正回答。将预测值和残差附加到熊猫数据框

数据帧目前看起来是这样的:

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 

和所有我想是返回拥有从Y = X1 + X2每个观测值的预测值和剩余一个数据帧:

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 

我试着用statsmodels和pandas解决这个问题,一直没能解决。提前致谢!

回答

5

下面是使用来自statsmodels代替大熊猫OLS模型OLS模型亚历山大的回答的变化。我们可以使用公式或数组/ DataFrame接口来模型。

fittedvaluesresid是正确索引的熊猫系列。 predict不返回熊猫系列。

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 

作为预览,有在statsmodels主(0.7)模型结果的扩展预测方法,但是API尚未解决:

>>> 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

谢谢,这是一个巨大的帮助! –

1

因此,形成你的问题很有礼貌,因为贡献者很容易运行你的代码。

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 

然后调用df.head()产量:

  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 

现在对于你的问题,这是非常简单与计算值添加列,但我不与你的样本数据,同意:

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

对我来说,这些产量:

  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 

希望这有助于!

+1

要添加其是现有的算术组合列列你也可以做'df.eval('y_hat = x1 + y1')'这很好,特别是如果你的DataFrame名字很长 – JoeCondron

+0

非常有帮助。将来确保添加数据帧源代码。谢谢! –

1

这应该是自我解释。

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

这很简单,更好。 –