Python:在一组数字中寻找趋势

2024-04-29 00:03:58 发布

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

我有一个Python中的数字列表,如下所示:

x = [12, 34, 29, 38, 34, 51, 29, 34, 47, 34, 55, 94, 68, 81]

从这些数字中找出趋势的最佳方法是什么?我不想预测下一个数字是什么,我只想输出很多组数字的趋势,以便比较趋势。

编辑:按趋势,我想用数字表示数字是增加还是减少以及以什么速度增加。我的数学水平不高,所以这可能有一个合适的名字!

编辑2:看起来我真正想要的是线性最佳拟合的协同效率。在Python中,最好的方法是什么?


Tags: 方法编辑列表水平线性数字数学名字
3条回答

你的意思可能是你想把这些数字画在一张图上,然后在图上找到一条直线,在直线和数字之间的总距离是最小的?这叫做线性回归

def linreg(X, Y):
    """
    return a,b in solution to y = ax + b such that root mean square distance between trend line and original points is minimized
    """
    N = len(X)
    Sx = Sy = Sxx = Syy = Sxy = 0.0
    for x, y in zip(X, Y):
        Sx = Sx + x
        Sy = Sy + y
        Sxx = Sxx + x*x
        Syy = Syy + y*y
        Sxy = Sxy + x*y
    det = Sxx * N - Sx * Sx
    return (Sxy * N - Sy * Sx)/det, (Sxx * Sy - Sx * Sxy)/det


x = [12, 34, 29, 38, 34, 51, 29, 34, 47, 34, 55, 94, 68, 81]
a,b = linreg(range(len(x)),x)  //your x,y are switched from standard notation

趋势线不太可能穿过原始点,但它将尽可能接近直线可以得到的原始点。使用该趋势线(a,b)的梯度和截距值,您将能够推断出超过数组末尾的线:

extrapolatedtrendline=[a*index + b for index in range(20)] //replace 20 with desired trend length

你可以做一个least squares fit的数据。

使用this page中的公式:

y = [12, 34, 29, 38, 34, 51, 29, 34, 47, 34, 55, 94, 68, 81]
N = len(y)
x = range(N)
B = (sum(x[i] * y[i] for i in xrange(N)) - 1./N*sum(x)*sum(y)) / (sum(x[i]**2 for i in xrange(N)) - 1./N*sum(x)**2)
A = 1.*sum(y)/N - B * 1.*sum(x)/N
print "%f + %f * x" % (A, B)

它会打印最佳拟合线的起始值和增量。

Keith提供的链接或Riaz提供的答案可能有助于获得poly-fit,但如果有的话,总是建议使用库,对于手头的问题,numpy提供了一个极好的多项式拟合函数,名为polyfit。可以使用polyfit将数据拟合到任意程度的方程上。

下面是一个使用numpy将数据拟合为y=ax+b形式的线性方程的示例

>>> data = [12, 34, 29, 38, 34, 51, 29, 34, 47, 34, 55, 94, 68, 81]
>>> x = np.arange(0,len(data))
>>> y=np.array(data)
>>> z = np.polyfit(x,y,1)
>>> print "{0}x + {1}".format(*z)
4.32527472527x + 17.6
>>> 

类似地,二次拟合将是

>>> print "{0}x^2 + {1}x + {2}".format(*z)
0.311126373626x^2 + 0.280631868132x + 25.6892857143
>>> 

相关问题 更多 >