趋势的最佳契合线

时间:2019-03-14 16:18:43

标签: python pandas dataframe matplotlib

我有以下数据

df = pd.DataFrame({ 
'region'  : ['a', 'a', 'a','a',' a','a','a', 's', 's','s','l','a','c','a', 'e','a','g', 'd','c','d','a','f','a','a','a'],
'month_number' : [5, 12, 3, 12, 3, 6,7,8,9,10,11,12,4,5,2,6,7,8,3, 4, 7, 6,7,8,8],
'score' : [2.5, 5, 3.5, 2.5, 5.5, 3.5,2,3.5,4,2,1.5,1,1.5,4,5.5,2,3,1,2,3.5,4,2,3.5,3,4]})

我想计算一个地区的分数平均值,并确定其一年中的趋势,最后,我想找到一条最合适的线,以查看趋势是否随着时间上升或下降。 (不是预测值,只是平均值)

我过滤了一个区域“ a”:

filtered = df[(df['region'] == 'a')]

并创建了一个趋势:

filtered.groupby(['month_number','region']).mean()['score'].unstack().plot(figsize=(10,6))

这给出了以下内容: enter image description here

现在,我被困在如何适应趋势的最佳趋势这一部分上。毕竟,我的目标是创建一个列,该列的正负值表示该区域的上升或下降趋势。如果有其他方法可以解决,我想听听。

2 个答案:

答案 0 :(得分:1)

您可以使用seaborn's回归图regplot进行以下操作。阴影区域是置信区间。

import seaborn as sns
import pandas as pd

df = pd.DataFrame({ 
'region'  : ['a', 'a', 'a','a',' a','a','a', 's', 's','s','l','a','c','a', 'e','a','g', 'd','c','d','a','f','a','a','a'],
'month_number' : [5, 12, 3, 12, 3, 6,7,8,9,10,11,12,4,5,2,6,7,8,3, 4, 7, 6,7,8,8],
'score' : [2.5, 5, 3.5, 2.5, 5.5, 3.5,2,3.5,4,2,1.5,1,1.5,4,5.5,2,3,1,2,3.5,4,2,3.5,3,4]})

filtered = df[(df['region'] == 'a')]
df1 = filtered.groupby(['month_number','region']).mean()['score'].unstack()
sns.regplot(x=df1.index.tolist(), y=df1['a'], data=df1)

enter image description here

如果您不想使用阴影置信区间,可以使用ci=0作为

sns.regplot(x=df1.index.tolist(), y=df1['a'], data=df1, ci=0)

enter image description here

答案 1 :(得分:1)

如果只想绘制直线拟合,请使用Seaborn。

但是,如果要计算适合数据的直线,请使用numpy.polyfit

import numpy as np
f1 = filtered.groupby('month_number').mean().reset_index()
x = f1.month_number.values
y = f1.score.values
m, c = np.polyfit(x, y, 1)

您已经计算出点的斜率和y轴截距。

您可以按以下方式计算位置上方和下方的点:

yHat = m*x + c
yError = y - yHat

对于新列,只需使用错误值:

f1['HiLo'] = [ ('+' if m else '-')  for m in yError>0]

您将获得加减。.

month_number     score HiLo
           3  3.500000    +
           5  3.250000    -
           6  2.750000    -
           7  3.166667    +
           8  3.500000    +
          12  2.833333    -