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


有什么建议可以改善吗?

最佳答案

只需将您定义的方法转换为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

关于python - 将预测残差追加到 Pandas 数据框-按组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44959410/

10-12 16:58