2017-07-06 64 views
1

此问题扩展了this的问题,但现在我想为单独的群组添加残差将预测残差附加到熊猫数据框 - 按群组

那么,当你想为单独的组运行回归时如何追加残差?

这里是数据帧:

df = pd.DataFrame({'gp': [1,1,1,1,1,2,2,2,2,2], 
       'x1': [3.17, 4.76, 4.17, 8.70, 11.45, 3.17, 4.76, 4.17, 8.70, 11.45], 
       'x2': [23, 26, 73, 72, 16, 26, 73, 72, 16, 25], 
       'y': [880.37, 716.20, 974.79, 322.80, 1054.25, 980.37, 816.20, 1074.79, 522.80, 1254.25]}, 
       index=np.arange(10, 30, 2)) 

现在,我想运行的两个组(GP)分开的回归,并在一个单独的列追加的残差。

我尝试这样的代码,但它仅填充最后回归组的残差(GP = 2):

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

def groupreg(df, regmodel): 
    groups = df.groupby('gp') 
    for item, group in groups: 
     df['residual'] = sm.ols(formula=regmodel, data=group).fit().resid 
    return (df) 

regmodel = 'y ~ x1 + x2' 

df = groupreg(df,regmodel) 

我发现一种方法来破解该问题,但是代码是长烯看起来低效:

def groupreg2(df, regmodel): 
    groups = df.groupby('gp') 
    i = 0 
    resname='residual' 
    for item, group in groups: 
     data = group.copy() 
     data[resname] = sm.ols(formula=regmodel, data=data).fit().resid 
     if i == 0: 
      i = 1 
      dout = data[resname].copy() 
     else: 
      dout = dout.append(data[resname].copy()) 

    df = pd.concat([df,dout],axis=1) 
    return (df) 

    df = groupreg2(df,regmodel) 

有什么建议要改进?

回答

1

只需简单的打开定义的方法到您在每个GP传递groupby.apply()

def groupreg(g): 
    g['residual'] = sm.ols(formula=regmodel, data=g).fit().resid 
    return g 

df = df.groupby('gp').apply(groupreg) 
print(df) 

#  gp  x1 x2  y residual 
# 10 1 3.17 23 880.37 -43.579309 
# 12 1 4.76 26 716.20 -174.532201 
# 14 1 4.17 73 974.79 318.634921 
# 16 1 8.70 72 322.80 -287.710952 
# 18 1 11.45 16 1054.25 187.187542 
# 20 2 3.17 26 980.37 174.295283 
# 22 2 4.76 73 816.20 -173.045597 
# 24 2 4.17 72 1074.79 101.623955 
# 26 2 8.70 16 522.80 -372.840833 
# 28 2 11.45 25 1254.25 269.967192 
0

我发现你的第一个解决方案的问题,那就是你分配结果原数据帧(DF),而应该将其分配给该组,这样的:

def groupreg(df, regmodel): 
    groups = df.groupby('gp') 
    for item, group in groups: 
     group['residual'] = sm.ols(formula=regmodel, data=group).fit().resid 
    return (df) 

只是略有变化,但它现在按预期工作。

+0

在我的Python你的建议不工作:这是执行代码时我收到:值是尝试将被设置在来自DataFrame的切片的副本上。 尝试使用.loc [row_indexer,col_indexer] =值改为 –