如何处理statsmodel.apiOLS效率
How to deal with statsmodel.api OLS efficiency
我有一个 df
由列组成:industry
、comp_id
、year
、y
和 x1, 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
我有一个 df
由列组成:industry
、comp_id
、year
、y
和 x1, 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