使用curve_fit拟合洛伦兹曲线时出现维度不匹配TypeError求助
解决curve_fit的TypeError: Improper input问题
你遇到的这个错误完全是个小疏忽——你的洛伦兹函数里用了方括号[]代替了圆括号(),这导致函数返回的不是和输入x同维度的数组,而是一个单元素列表,curve_fit自然就懵了,因为它期望拟合函数的输出长度和输入x的长度一致。
错误原因拆解
看你的洛伦兹函数定义:
def lorentz_function(x, a, x0,f): w = f/2 # 半高半宽 return a*w/ [(x-x0)**2+w**2]
这里的[(x-x0)**2+w**2]是创建了一个包含numpy数组的列表,而不是对每个x元素进行运算的表达式。当你把这个列表和a*w做除法时,结果是一个长度为1的对象,而你的time_trim是长度为190的数组(1170-980),curve_fit发现拟合函数输出的维度和输入y的维度不匹配,就抛出了N=3 must not exceed M=1的错误(N是参数数量,M是它误以为的有效数据点数量)。
修正后的洛伦兹拟合代码
把方括号改成圆括号,确保运算都是numpy的数组广播运算:
# x为x值,a为振幅,x0为中心值,f为半峰全宽 def lorentz_function(x, a, x0,f): w = f/2 # 半高半宽 return a*w / ((x-x0)**2 + w**2) # 这里用圆括号代替方括号 # 执行拟合 popt, pcov = curve_fit(lorentz_function, time_trim, voltage_trim, p0=[1,.4,0.1]) perr = np.sqrt(np.diag(pcov)) # 绘制洛伦兹拟合图 plt.figure(3) plt.plot(time_trim, lorentz_function(time_trim, *popt), label = "Lorentz fit") plt.plot(time_trim, voltage_trim, "-b", label="Raw data") plt.legend() plt.show()
额外排查小技巧
以后遇到类似维度问题,可以先单独测试拟合函数,比如调用lorentz_function(time_trim, 1, .4, 0.1),看看返回的数组长度是否和time_trim一致,这样能快速定位函数输出的维度问题。如果拟合结果不理想,还可以根据原始数据调整初始参数p0的取值,让拟合收敛更顺利。
内容的提问来源于stack exchange,提问作者newbiecode
相关产品推荐
相关产品推荐

