我需要将一个线性方程拟合到一个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 '''
答案 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'])