Scipy Curve_fit拟合三角函数模型报错:解包值不足问题排查
三角函数曲线拟合报错问题解决
错误原因
curve_fit函数的返回值是两个元素:第一个是拟合得到的参数数组,第二个是参数的协方差矩阵。你试图直接将其解包为4个单独变量,这就导致了“解包值不足”的错误。
另外代码里还有两个小问题:
- 绘图时使用了未定义的变量
tid和vannstand,应该替换为定义好的time和waterlevel - 初始值
p0的第一个参数设为0会导致拟合陷入常数函数,无法收敛到正确的三角函数,需要调整为合理的初始角频率值。
修正后的代码
from pylab import * from scipy.optimize import curve_fit # 原始数据 time = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23] waterlevel = [125,199,223,176,101,73,109,181,219,188,122,85] # 定义拟合函数:自变量t在前,待拟合参数x(角频率)、A(振幅)、phi(相移)、d(垂直偏移)在后 def h(t, x, A, phi, d): return A * sin(x * t + phi) + d # 接收curve_fit的返回值:参数数组和协方差矩阵 # p0初始值参考:角频率x≈2π/12≈0.52(潮汐周期约12小时),振幅A≈(最大值-最小值)/2≈75,d≈均值≈150 params, covariance = curve_fit(h, time, waterlevel, p0=[0.5, 75, -1, 150]) # 从参数数组中提取各个拟合参数 x_fit, A_fit, phi_fit, d_fit = params # 打印结果 print("角频率x =", round(x_fit, 4)) print("周期T =", round(2*pi / x_fit, 2), "小时") # 周期T=2π/角频率x print("振幅A =", round(A_fit, 2)) print("相移phi =", round(phi_fit, 2)) print("垂直偏移d =", round(d_fit, 2)) # 绘图展示 plot(time, waterlevel, "o", label="原始数据") xlabel("Time (hours)") ylabel("Water level (cm)") t = linspace(0, 24, 1000) plot(t, h(t, x_fit, A_fit, phi_fit, d_fit), "r", label="拟合曲线") legend() show()
关键说明
- 正确接收返回值:必须用两个变量接收
curve_fit的输出,再从第一个参数数组中提取各个拟合参数 - 初始值设置:初始值
p0的顺序要和拟合函数h的参数顺序(x,A,phi,d)完全对应,且要设置合理的初始值才能让拟合收敛。这里根据潮汐数据的周期特性,设置角频率初始值为0.5(对应周期约12.57小时),符合实际潮汐规律 - 周期计算:你要的“周期”是指完成一次振荡的时间,和拟合参数中的角频率
x的关系是 $T = \frac{2\pi}{x}$,所以可以通过拟合得到的x计算出实际周期
内容的提问来源于stack exchange,提问作者Nikola Golis
相关产品推荐
相关产品推荐

