我有以下x,y数据
x = np.array([-1.280199006, -1.136209343, -1.048070216, -0.9616764178, -0.8752826199, -0.7871434926, -0.6981317008, -0.6108652382, -0.5235987756, -0.4372049776,
-0.3490658504, -0.2644173817, -0.1762782545,
-0.0907571211, 0, 0.09250245036, 0.1762782545, 0.2661627109, 0.3516838443, 0.4345869837, 0.529707428, 0.6108652382, 0.7007496947, 0.7880161573, 0.872664626,
0.9616764178, 1.055051533, 1.160643953, 1.274090354, 1.413716694])
y = np.array([-0.05860218717, -0.05275174988, -0.04961805822, -0.02860635697, -0.04150466841, -0.02672933264, -0.02422597285, -0.03056176732, -0.02885180089, -0.02085851636,
-0.02873319291, -0.02374542821, -0.02132671806,
-0.02088924602, -0.0216617248, -0.01835553738, -0.01369531698, -0.01331112368, -0.01156455074, -0.009163690404, -0.003542622659, -0.003515924976, -0.003828831726, -0.002622163805, -0.001622083468,
-0.00297346133, -0.001845415856, -0.001913228234, -0.001495496086, -0.001454621173])
并希望用至少3个线段的numpy分段拟合
我试过了
def piecewise_linear(x, x0, x1, y0, y1, k1, k2, k3):
conds = [x<x0, (x>=x0) & (x<x1),x>=x1]
funcs = [lambda x:k1*(x-x0) + y0, lambda x:k2*(x-x0) + y0, lambda x:k2*(x1-x0) + y0 + k3*(x-x1)]
return np.piecewise(x, conds, funcs)
p , e = curve_fit(piecewise_linear, x, y)
xd = np.linspace(-1.3, 1.5, 100)
plt.plot(x, y, "o")
plt.plot(xd, piecewise_linear(xd, *p))
但它设置
x1 = 0.266162745743
和
x0 = 0.323723668069
即x0> x1。最终进行2段拟合。
我究竟做错了什么?我需要缩放数据吗?更普遍地说,有一种方法可以控制分段使用多少段?
最佳答案
问题是piecewise
返回一个数组而不是一个函数。
因此,y1
不是独立的参数。
定义函数的一种方法是在算术上下文中使用布尔值(True = 1,False = 0):
def f(x,x0,y0,x1,k1,k2,k3):
# x0,y0 : first breakpoint
# x1 : second breakpoint
# k1,k2,k3 : 3 slopes.
y1=y0+ k2*(x1-x0) # for continuity
return (
(x<x0) * (y0 + k1*(x-x0)) +
((x>=x0) & (x<x1)) * (y0 + k2*(x-x0)) +
(x>=x1) * (y1 + k3*(x-x1)))
p0=(-.7,-0.03,.5,0.03,0.02,0.01)
p , e = curve_fit(f, x, y,p0)
close()
plt.plot(x, y, "o")
plot(x,f(x,*p))
show()
适合。
关于python - 无法对3个分段分段执行numpy,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41895233/