我希望检查多个实体的趋势(SysNr)
我的数据跨越3年(2014,2015,2016)
我正在查看大量变量,但会将此问题限制为一个(' res_f_r')
我的DataFrame看起来像这样
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)进行线性回归并返回斜率和截距
我想要的输出是
SysNr intercept slope
0 1 300000 50000
1 2 400000 -50000
有什么想法吗?
答案 0 :(得分:5)
所以我不知道为什么我们的拦截值不同(也许我犯了一个错误,或者您的给定数据不是您期望处理的完整数据),但我建议您使用np.polyfit
或者您选择的工具(scikit-learn,scipy.stats.linregress,...)与groupby结合使用:
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
之后,美化它:
In [43]: df.groupby("SysNr").apply(
...: lambda g: np.polyfit(g.RegnskabsAar, g.res_f_r, 1)).apply(
...: pd.Series).rename(columns={0:'slope', 1:'intercept'}).reset_index()
Out[43]:
SysNr slope intercept
0 1 50000.0 -1.003500e+08
1 2 -50000.0 1.010500e+08
因为您在评论的另一个答案中询问了如何处理某些SysNr
的缺失年份:
只需删除NaNs
即可获得有效的线性回归。当然你也可以根据你想要达到的目标来填充它们,但从我的观点来看,这并没有那么有用。
如果实体只有一年的数据,则无法对其进行有用的线性回归。但是你可以(如果你想要并且适合你的情况,请在需要时提供有关数据的更多信息)以某种方式推断其他实体的斜率到这个并计算截距。当然,你必须对实体斜率的分布做一些假设(例如线性,然后sysNr 3的斜率为-150000.0
)。
答案 1 :(得分:2)
您也可以使用linregress
中的scipy.stats
与groupby
中的pandas
:
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
结果:
SysNr slope intercept r_value p_value std_err
0 1 50000.0 -100350000.0 1.0 9.003163e-11 0.0
1 2 -50000.0 101050000.0 -1.0 9.003163e-11 0.0