根据线性回归R ^ 2值更改pandas数据帧

时间:2015-12-13 14:35:24

标签: python pandas scipy

我需要将一个线性方程拟合到一个pandas数据帧,并根据线的拟合(R ^ 2值)我需要删除数据帧的行。我正在使用SciPy linregress功能。我已经尝试了几种方法,但还没有找到一种方法可以解决我需要它的方式:

slope, intercept, r_value, p_value, std_err = stats.linregress([df['p_rel',df['y_BET'])
r_sq = r_value ** 2

if r_sq < 0.995:
    '''remove last row from dataframe and run linregress again. repeat this until r_sq >= 0.995 '''

2 个答案:

答案 0 :(得分:1)

为什么不将它放入函数中?

def regress(df):
    slope, intercept, r_value, p_value, std_err = stats.linregress(df['p_rel'], df['y_BET'])

    if r_value ** 2 < 0.995:
        regress(df.iloc[:-1, :])  # call again and regress with last row removed
    else:
        DO STUFF WITH RESULT

这个递归保证结束:我们正在回归两列(所以两个n x 1结构),并递归地将其更新为n-1, n-2, ..., 2。它最迟在2处停止,因为两个2 x 1结构的回归保证R平方等于1(因此在if语句中求值为false)。

修改:如果你想在函数外部使用结果(请参阅注释),这可行:

def regress(df):
    slope, intercept, r_value, p_value, std_err = stats.linregress(df['p_rel'], df['y_BET'])

    if r_value ** 2 < 0.995:
        return regress(df.iloc[:-1, :])  # call again and regress with last row removed
    else:
        return slope, intercept, r_value, p_value, std_err 

# call like so:
slope, intercept, r_value, p_value, std_err = regress(df)

# use the results here

答案 1 :(得分:1)

您可以使用generator expression来创建迭代器 它可以迭代linregress次调用的序列。因为它是一个 对于一次通过迭代器,对linregress的调用将被延迟,直到需要为止。

然后你可以使用itertools.dropwhile迭代生成器表达式,删除结果直到R**2值大于0.995:

import scipy.stats as stats
import itertools as IT
regressions = (stats.linregress([df['p_rel'].iloc[:-i], df['y_BET'].iloc[:-i]) 
                                for i in range(len(df)))
slope, intercept, r_value, p_value, std_err = next(IT.dropwhile(
    lambda x: x[2]**2 < 0.995, regressions))

你也可以将它包装在一个函数中:

def regress_dropping_tail_outliers(x, y, threshold=0.995):
    regressions = (stats.linregress([x.iloc[:-i], y.iloc[:-i]) for i in range(len(x)))
    return next(IT.dropwhile(lambda x: x[2]**2 < threshold, regressions))

slope, intercept, r_value, p_value, std_err = regress_dropping_tail_outliers(
    df['p_rel'], df['y_BET'])