将预测残差附加到pandas数据帧 - 按组

时间:2017-07-06 21:46:39

标签: python pandas regression

此问题扩展了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)

有任何改进建议吗?

2 个答案:

答案 0 :(得分:1)

只需将您定义的方法转换为groupby.apply(),然后传入每个 gp

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

答案 1 :(得分: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)

稍微改变一下,但它现在按预期工作。