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!再次感谢