Finding the point of a slope change as a free parameter- Python
假设我有两个数据列表,如下所示:
1 2 | x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] y = [1, 2, 3, 4, 5, 6, 8, 10, 12, 14] |
也就是说,很明显,仅仅将一条直线拟合到这些数据上是行不通的,而是在数据中的某个点改变了坡度。(很明显,我们可以很容易地从这个数据集中找出变化的位置,但在我正在处理的数据集中并不是很清楚,所以我们忽略它。)我猜,关于导数的一些东西,但这里的重点是我想把它当作一个自由参数,我说"这是这个点,+/-这个不确定性,这里是前面的线性斜率。在这一点之后。"
注意,如果数组更简单的话,我可以用它来做这个。谢谢!
以下是您的数据图:
。
你需要找到两个斜率(=取两个导数)。首先,找出每两点之间的坡度(使用
1 2 3 4 5 6 | import numpy as np x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10],dtype=np.float) y = np.array([1, 2, 3, 4, 5, 6, 8, 10, 12, 14],dtype=np.float) m = np.diff(y)/np.diff(x) print (m) # [ 1. 1. 1. 1. 1. 2. 2. 2. 2.] |
显然,在第六个区间(第六点和第七点之间),坡度从1变为2。然后取这个数组的导数,它告诉你坡度何时改变:
1 2 | print (np.diff(m)) [ 0. 0. 0. 0. 1. 0. 0. 0.] |
。
要查找非零值的索引:
1 2 3 | idx = np.nonzero(np.diff(m))[0] print (idx) # 4 |
。
因为我们对x取了一个导数,并且在python中指数从零开始,所以
您可以将坡度计算为每对点之间的差(一阶导数)。然后检查坡度变化的位置(二阶导数)。如果它发生变化,将索引位置附加到
请注意,第一个点没有唯一的坡度。第二对点会给你一个坡度,但是你需要第三对点才能测量坡度的变化。
1 2 3 4 5 6 7 8 9 10 | idx = [] prior_slope = float(y[1] - y[0]) / (x[1] - x[0]) for n in range(2, len(x)): # Start from 3rd pair of points. slope = float(y[n] - y[n - 1]) / (x[n] - x[n - 1]) if slope != prior_slope: idx.append(n) prior_slope = slope >>> idx [6] |
当然,在熊猫或麻木的环境中,这可以更有效地完成,但我只是给您一个简单的python 2解决方案。
一个简单的条件列表理解也应该是相当有效的,尽管它更难理解。
1 2 3 | idx = [n for n in range(2, len(x)) if float(y[n] - y[n - 1]) / (x[n] - x[n - 1]) != float(y[n - 1] - y[n - 2]) / (x[n - 1] - x[n - 2])] |
。
我不太清楚你想要什么,但是你可以用这种方式看到进化过程(导数):
1 2 3 4 | >>> y = [1, 2, 3, 4, 5, 6, 8, 10, 12, 14] >>> dy=[y[i+1]-y[i] for i in range(len(y)-1)] >>> dy [1, 1, 1, 1, 1, 2, 2, 2, 2] |
然后找出它的变化点(二阶导数):
1 2 3 | >>> dpy=[dy[i+1]-dy[i] for i in range(len(dy)-1)] >>> dpy [0, 0, 0, 0, 1, 0, 0, 0] |
号
如果需要此点的索引:
1 2 | >>> dpy.index(1) 4 |
这可以为您提供坡度变化前最后一个点的值:
1 2 3 | >>> change=dpy.index(1) >>> y[change] 5 |
。
在您的