基于pandas数据帧的简单线性回归

2024-04-28 12:13:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在查看一些实体的趋势(SysNr)

我有3年的数据(201420152016)

我看了大量的变量,但将把这个问题限制在一个('res\u'r')

我的数据框看起来像这样

d = [
    {'RegnskabsAar': 2014, 'SysNr': 1, 'res_f_r': 350000},
    {'RegnskabsAar': 2015, 'SysNr': 1, 'res_f_r': 400000},
    {'RegnskabsAar': 2016, 'SysNr': 1, 'res_f_r': 450000},
    {'RegnskabsAar': 2014, 'SysNr': 2, 'res_f_r': 350000},
    {'RegnskabsAar': 2015, 'SysNr': 2, 'res_f_r': 300000},
    {'RegnskabsAar': 2016, 'SysNr': 2, 'res_f_r': 250000},
]

df = pd.DataFrame(d)



   RegnskabsAar  SysNr  res_f_r
0          2014      1   350000
1          2015      1   400000
2          2016      1   450000
3          2014      2   350000
4          2015      2   300000
5          2016      2   250000

我的愿望是对每个实体(SysNr)进行线性回归,并返回斜率和截距

我想要的以上输出是

^{pr2}$

有什么想法吗?在


Tags: 数据实体dataframedfres线性趋势pd
2条回答

您也可以将scipy.stats中的linregresspandas中的groupby一起使用:

from scipy.stats import linregress

# groupby column
grouped = df.groupby('SysNr')

# https://stackoverflow.com/a/14775604/5916727
# apply linear regression to each group
result_df = pd.DataFrame(grouped.apply(lambda x: linregress(x['RegnskabsAar'], x['res_f_r']))).reset_index()

# https://stackoverflow.com/a/29550458/5916727
# expand result to each column
result_df[['slope', 'intercept', 'r_value', 'p_value', 'std_err']] = result_df[0].apply(pd.Series)

# drop initial column with all in one
del result_df[0]

result_df

结果:

^{pr2}$

因此,我不知道为什么截距值不同(可能我犯了个错误,或者您的给定数据不是您希望处理的完整数据),但我建议您将^{}或您选择的工具(scikit-learnscipy.stats.linregress,…)与groupby和apply结合使用:

In [25]: df.groupby("SysNr").apply(lambda g: np.polyfit(g.RegnskabsAar, g.res_f_r, 1))
Out[25]:
SysNr
1    [49999.99999999048, -100349999.99998075]
2    [-49999.99999999045, 101049999.99998072]
dtype: object

之后,美化它:

^{pr2}$

编辑:

因为您在评论中询问了另一个答案,即如何处理某些SysNr的缺失年份: 只需删除NaNs即可获得有效的线性回归。当然,你也可以根据你想要达到的目标,用平均值来填充它们,但在我看来,这并没有什么帮助。在

如果实体只有一年的数据,就不能对其进行有效的线性回归。但是你可以(如果你想并且这适合你的情况,如果需要的话,请提供更多关于数据的信息)以某种方式外推其他实体的斜率并计算截距。当然,你必须对实体的斜率分布做一些假设(例如线性的,那么sysnr3的斜率是-150000.0)。在

相关问题 更多 >