Python:如何按组运行多元单变量回归
假设我有一个Python:如何按组运行多元单变量回归,python,pandas,Python,Pandas,假设我有一个DataFrame,其中有一列y变量和多列x变量。我希望能够运行yvsx1,yvsx2,…,等等的多个单变量回归,并将预测存储回数据框。我还需要通过一个组变量来实现这一点 import statsmodels.api as sm import pandas as pd df = pd.DataFrame({ 'y': np.random.randn(20), 'x1': np.random.randn(20), 'x2': np.random.randn(20),
DataFrame
,其中有一列y
变量和多列x
变量。我希望能够运行y
vsx1
,y
vsx2
,…,等等的多个单变量回归,并将预测存储回数据框
。我还需要通过一个组变量来实现这一点
import statsmodels.api as sm
import pandas as pd
df = pd.DataFrame({
'y': np.random.randn(20),
'x1': np.random.randn(20),
'x2': np.random.randn(20),
'grp': ['a', 'b'] * 10})
def ols_res(x, y):
return sm.OLS(y, x).fit().predict()
df.groupby('grp').apply(ols_res) # This does not work
上面的代码显然不起作用。我不清楚如何在使
apply
遍历x
列(x1
,x2
,…)的同时正确地将固定的y
传递给函数。我怀疑可能有一个非常聪明的单线解决方案可以做到这一点。有什么想法吗?传递给apply
的函数必须将pandas.DataFrame
作为第一个参数。您可以将其他关键字或位置参数传递给apply
,这些参数将传递给applied函数。因此,您的示例只需稍加修改即可工作。将ols\u res
更改为
def ols_res(df, xcols, ycol):
return sm.OLS(df[ycol], df[xcols]).fit().predict()
然后,您可以像这样使用groupby
和apply
df.groupby('grp').apply(ols_res, xcols=['x1', 'x2'], ycol='y')
或
编辑
上述代码不运行多个单变量回归。相反,它对每组进行一次多元回归。不过,只要(再)稍加修改,它就可以了
def ols_res(df, xcols, ycol):
return pd.DataFrame({xcol : sm.OLS(df[ycol], df[xcol]).fit().predict() for xcol in xcols})
编辑2
尽管上述解决方案可行,但我认为下面的方法更为简单
import statsmodels.api as sm
import pandas as pd
import numpy as np
df = pd.DataFrame({
'y': np.random.randn(20),
'x1': np.random.randn(20),
'x2': np.random.randn(20),
'grp': ['a', 'b'] * 10})
def ols_res(x, y):
return pd.Series(sm.OLS(y, x).fit().predict())
df.groupby('grp').apply(lambda x : x[['x1', 'x2']].apply(ols_res, y=x['y']))
出于某种原因,如果我像最初一样定义
ols_res()
,那么结果的DataFrame
在索引中没有组标签。事实上,我相信这会运行一个多元回归,而不是在列中循环并运行多个单变量回归。很抱歉,我本应该更仔细地阅读这个问题。请看我的编辑。
import statsmodels.api as sm
import pandas as pd
import numpy as np
df = pd.DataFrame({
'y': np.random.randn(20),
'x1': np.random.randn(20),
'x2': np.random.randn(20),
'grp': ['a', 'b'] * 10})
def ols_res(x, y):
return pd.Series(sm.OLS(y, x).fit().predict())
df.groupby('grp').apply(lambda x : x[['x1', 'x2']].apply(ols_res, y=x['y']))