如何处理statsmodel.apiOLS效率

How to deal with statsmodel.api OLS efficiency

我有一个 df 由列组成:industrycomp_idyearyx1, x2, x3, ..。数据如下所示:

   indus  comp_id  year      y   x1    x2     x3  other_var
0      A      100  2000   90.0    9  44.0   95.0         66
1      A      100  2001   59.0   65   4.0   63.0         52
2      A      100  2002   75.0   49  29.0   64.0         27
3      A      100  2003   83.0   29  86.0   48.0         57
4      A      100  2004   82.0   64  43.0   67.0         58
5      A      100  2005   88.0   30  54.0   75.0         29
6      A      100  2006   91.0    3  46.0  100.0         68
7      A      101  2005    NaN   65  53.0  100.0         57
8      A      101  2006   83.0   56  67.0   60.0         40
9      A      101  2006  112.0  100  97.0   59.0         54
10     A      101  2007   53.0   95   NaN    3.0         55
11     A      101  2007  113.0   28  77.0   96.0         30
12     A      101  2008   84.0    2  79.0   57.0         54
13     A      101  2008   53.0   19  12.0    NaN         62
14     B      102  2002   83.0   92  88.0   31.0         31
15     B      102  2003  102.0    7  67.0   96.0         28
16     B      103  2003    NaN   49   NaN   72.0         22
17     B      103  2004    NaN   60   NaN   52.0         69
18     B      103  2005    NaN   74   NaN   44.0         49
19     B      103  2006    NaN   21   NaN   31.0         38
20     B      103  2007    NaN   69   NaN   36.0         28
21     B      103  2008    NaN    5   NaN    6.0         32
22     B      103  2009    NaN   22   NaN   10.0         61

我需要 运行 按公司集团逐年进行回归,并 return 具有残差的新列。我的代码是:

def func_reg_err(df, yvar, xvar, alpha=True):
    y = df[yvar].copy()
    x = pd.DataFrame(df[xvar].copy())
    if alpha == True:
        x['intercept'] = 1.
    mod = sm.OLS(y,x, missing='drop')
    res = mod.fit()
    err = y - mod.predict(res.params, x)
    return err

要运行按组回归,我使用如下代码:

df['residual'] = df.groupby('comp_id', group_keys=False).apply(func_reg_err, 'y', ['x1', 'x2', 'x3'], False)

如果数据很好,那么什么也不会发生,代码运行顺利。然而,在我的df中,有很多公司有Missing个数据(一整列)或者观察太少的公司(只有1个或2个)。在示例中,它们是 comp_id = 102, 1003 的公司。一个只有 2 个观测值,另一个缺失值太多。这些公司使我的代码不断出现 returning 错误。

我可以通过创建 df 的副本来解决,然后手动过滤那些不合格的公司,运行 func_reg_err 然后 merge 返回 df 再次。但是,我认为这种方法只是一种变通解决方案。我正在寻找一种有效的方法来处理这个问题。

我想要的是那些不符合条件的组,residual列将return和np.Nan

您可以在辅助函数中定义可接受的最小样本长度(作为总长度或 one/all 回归列),例如:

def func_reg_err(df, yvar, xvar, alpha=True, min_samples=30):
    # Return NaNs only
    if len(df) < min_samples or (df.notnull().sum(1) < min_samples).any():
        return pd.Series(index=df.index)

    # Carry on with your regression
    y = df[yvar].copy()
    x = pd.DataFrame(df[xvar].copy())
    if alpha == True:
        x['intercept'] = 1.
    mod = sm.OLS(y,x, missing='drop')
    res = mod.fit()
    err = y - mod.predict(res.params, x)

    return err