Python Panda dataframe groupby和回归计算
我希望你身体好 我目前正试图在一组数据框架上计算回归,但没有成功。我成功地计算出了我想要的结果,但由于数据结构的原因,我真的不知道如何将结果重新整合到我的原始数据帧中。我尝试了两个函数 我为五分之一成功,并给你密码 很抱歉,这条消息太大了,但我正在尽可能地说清楚 套餐Python Panda dataframe groupby和回归计算,python,pandas,dataframe,group-by,regression,Python,Pandas,Dataframe,Group By,Regression,我希望你身体好 我目前正试图在一组数据框架上计算回归,但没有成功。我成功地计算出了我想要的结果,但由于数据结构的原因,我真的不知道如何将结果重新整合到我的原始数据帧中。我尝试了两个函数 我为五分之一成功,并给你密码 很抱歉,这条消息太大了,但我正在尽可能地说清楚 套餐 import pandas as pd from collections import OrderedDict import statsmodels.api as sm import numpy as np from sklear
import pandas as pd
from collections import OrderedDict
import statsmodels.api as sm
import numpy as np
from sklearn.linear_model import LinearRegression
功能
def regress(data, yvar, xvars):
Y = data[yvar]
X = data[xvars]
X['intercept'] = 1.
result = sm.OLS(Y, X).fit()
y_pred = result.predict()
residual = Y - y_pred
return residual
def Reg_func(x,y):
# Cross Sectional Regression
x = np.array(x).reshape((-1,1))
y = np.array(y)
model = LinearRegression().fit(x, y)
y_pred = model.intercept_ + np.sum(model.coef_ * x,axis=1)
residual = y - y_pred
return residual
# Quintile groupé par Axe
QC1 = df.groupby(['Axe'])['C1'].apply(lambda x: pd.qcut(x, 5, labels=False)+1)
print(QC1)
数据帧创建
ind = ['I1', 'I2', 'I3', 'I4', 'I5', 'I6', 'I7', 'I8', 'I9', 'I10', 'I11', 'I12', 'I13', 'I14', 'I15', 'I16', 'I17', 'I18', 'I19', 'I20']
Axe = ['A', 'A', 'B', 'A', 'A', 'A', 'A', 'B', 'A', 'A', 'A', 'B', 'B', 'A', 'B', 'B', 'B', 'B', 'B', 'B']
df = pd.DataFrame(np.random.randn(20, 2), index = ind, columns=['C1', 'C2'])
df.insert(0,'Axe',Axe)
如果你知道一个更好的方法来创建它,我会很高兴:)
计算
def regress(data, yvar, xvars):
Y = data[yvar]
X = data[xvars]
X['intercept'] = 1.
result = sm.OLS(Y, X).fit()
y_pred = result.predict()
residual = Y - y_pred
return residual
def Reg_func(x,y):
# Cross Sectional Regression
x = np.array(x).reshape((-1,1))
y = np.array(y)
model = LinearRegression().fit(x, y)
y_pred = model.intercept_ + np.sum(model.coef_ * x,axis=1)
residual = y - y_pred
return residual
# Quintile groupé par Axe
QC1 = df.groupby(['Axe'])['C1'].apply(lambda x: pd.qcut(x, 5, labels=False)+1)
print(QC1)
QC1尊重df结构,因此很容易将结果集成到df中
# Simple regression without groupby
res_reg = Reg_func(newdf['C1'], newdf['C2'])
Res_REg与df结构一致
# Regression per group with Reg_func fucntion
res_reg_group = (df.groupby('Axe').apply(lambda x: Reg_func(x['C1'], x['C2'])))
print(res_reg_group)
# Regression per group with regress function
res_reg_group2 = df.groupby('Axe').apply(regress, 'C1', ['C2'])
print(res_reg_group2)
由于it结构的原因,我真的不知道如何将结果重新整合到df中
# Regression per group with Reg_func fucntion
res_reg_group = (df.groupby('Axe').apply(lambda x: Reg_func(x['C1'], x['C2'])))
print(res_reg_group)
# Regression per group with regress function
res_reg_group2 = df.groupby('Axe').apply(regress, 'C1', ['C2'])
print(res_reg_group2)
res_reg_group2似乎有更好的结构(keep index),但不知道如何将其与我的df数据帧相结合。此外,此函数回归不适用于简单回归(没有groupby)
感谢您的帮助,请无后顾之忧
在第一种情况下,您可以分别检索每个组的残差,例如res\u reg\u group['A']
应保留残差的顺序(尽管您可能希望再次检查),在这种情况下,您可以根据它们的分组将它们放入新列中:
res_reg_group = (df.groupby('Axe').apply(lambda x: Reg_func(x['C1'], x['C2'])))
df.loc[df['Axe']=='A', 'res'] = res_reg_group['A']
df.loc[df['Axe']=='B', 'res'] = res_reg_group['B']
print(df)
Axe C1 C2 res
I1 A 1.624345 -0.611756 0.545826
I2 A -0.528172 -1.072969 -0.943326
I3 B 0.865408 -2.301539 -1.889825
I4 A 1.744812 -0.761207 0.453904
I5 A 0.319039 -0.249370 0.284860
I6 A 1.462108 -2.060141 -0.980035
I7 A -0.322417 -0.384054 -0.156153
I8 B 1.133769 -1.099891 -0.656326
I9 A -0.172428 -0.877858 -0.578330
I10 A 0.042214 0.582815 0.984847
I11 A -1.100619 1.144724 1.000992
I12 B 0.901591 0.502494 0.918503
I13 B 0.900856 -0.683728 -0.267807
I14 A -0.122890 -0.935769 -0.612584
I15 B -0.267888 0.530355 0.807559
I16 B -0.691661 -0.396754 -0.169848
I17 B -0.687173 -0.845206 -0.617767
I18 B -0.671246 -0.012665 0.216664
I19 B -1.117310 0.234416 0.410802
I20 B 1.659802 0.742044 1.248044
带索引
在第二种情况下,您需要使用一个索引,因此您可以使用公共索引合并两个数据帧:
res_reg_group2 = df.groupby('Axe').apply(regress, 'C1', ['C2'])
output = df.merge(res_reg_group2.droplevel(0), left_index=True, right_index=True,
suffixes=['', '_res'])
print(output)
Axe C1 C2 C1_res
I1 A 1.624345 -0.611756 1.277757
I2 A -0.528172 -1.072969 -1.143578
I3 B 0.865408 -2.301539 0.403997
I4 A 1.744812 -0.761207 1.311116
I5 A 0.319039 -0.249370 0.183668
I6 A 1.462108 -2.060141 0.271328
I7 A -0.322417 -0.384054 -0.536289
I8 B 1.133769 -1.099891 0.830338
I9 A -0.172428 -0.877858 -0.674114
I10 A 0.042214 0.582815 0.391883
I11 A -1.100619 1.144724 -0.423441
I12 B 0.901591 0.502494 0.808824
I13 B 0.900856 -0.683728 0.652137
I14 A -0.122890 -0.935769 -0.658330
I15 B -0.267888 0.530355 -0.356992
I16 B -0.691661 -0.396754 -0.902651
I17 B -0.687173 -0.845206 -0.957121
I18 B -0.671246 -0.012665 -0.831740
I19 B -1.117310 0.234416 -1.245321
I20 B 1.659802 0.742044 1.598529
我不知道为什么残差值不同,可能是statsmodels和sklearn之间的一些差异,但这就是你如何组合结果的方式谢谢Simon,我成功地做到了我想要的:)。@CedricC真棒!如果答案有用的话,别忘了接受:)不知道怎么做lol没有“接受按钮”或解决…@CedricC答案旁边的复选标记OK done!再次感谢