使用scipy.curve_fit一维方法实现二维曲面拟合报错求助
解决scipy.optimize.curve_fit二维曲面拟合时的索引错误
错误原因
你遇到的IndexError本质是:curve_fit在拟合迭代过程中,会对传入的自变量(此处为index_line)进行数值调整,可能生成非整数的浮点数作为索引参数。尽管初始的index_line是整数数组,但拟合过程中临时传入的索引值不符合numpy数组的索引类型要求,因此触发报错。
解决方案
无需通过索引间接获取x、y数据,直接将一维化的x_line和y_line作为二维自变量传入curve_fit,同时修改拟合函数的参数结构,让它直接接收x、y数据而非索引。这种方式逻辑更清晰,也从根源上避免了索引类型问题。
修改后的完整代码
import numpy as np import matplotlib.pyplot as plt from scipy.optimize import curve_fit ### 定义曲面公式与拟合函数 # 原始二维曲面公式 sag_eq = lambda x, y, x0, y0, z0, r, k: ((1/r)*((x-x0)**2+(y-y0)**2)**2) / (1+np.sqrt(1-(1+k)*(1/r)**2*((x-x0)**2+(y-y0)**2))) + z0 # 适配curve_fit的拟合函数:第一个参数接收x、y组成的元组 def sag_fit_func(x_y, x0, y0, z0, r, k): x, y = x_y return ((1/r)*((x-x0)**2+(y-y0)**2)**2) / (1+np.sqrt(1-(1+k)*(1/r)**2*((x-x0)**2+(y-y0)**2))) + z0 ### 生成带噪声的二维数据 x_dom = np.linspace(0,0.32, 2**8) y_dom = np.linspace(0,0.24, 2**7) param = [x_dom[-1]/2, y_dom[-1]/2, 0, -0.2, -1] zz = [] for y in y_dom: base = sag_eq(x_dom, y, param[0], param[1], param[2], param[3], param[4]) noise = np.random.rand(len(base)) zz.append(base+noise*1e-3) zz=np.array(zz) xx, yy = np.meshgrid(x_dom, y_dom) ### 转换为一维数组用于拟合 x_line = xx.reshape(len(x_dom)*len(y_dom)) y_line = yy.reshape(len(x_dom)*len(y_dom)) z_line = zz.reshape(len(x_dom)*len(y_dom)) ### 测试曲面生成(可选) surface_1 = sag_eq(xx, yy, param[0], param[1], param[2], param[3], param[4]) fig, [ax_data, ax_surf1] = plt.subplots(1,2) ax_data.contourf(xx, yy, zz); ax_data.set_title("原始数据曲面") ax_surf1.contourf(xx, yy, surface_1); ax_surf1.set_title("公式生成曲面") plt.show() fig, [ax_x, ax_y] = plt.subplots(1, 2) ax_x.scatter(x_line, z_line); ax_x.set_title("一维X-Z数据") ax_y.scatter(y_line, z_line); ax_y.set_title("一维Y-Z数据") plt.show() ### 执行拟合 popt, pcov = curve_fit(sag_fit_func, (x_line, y_line), z_line, p0=param) print("拟合得到的参数:", popt) # 验证拟合结果 fit_surface = sag_eq(xx, yy, *popt) fig, ax_fit = plt.subplots() ax_fit.contourf(xx, yy, fit_surface); ax_fit.set_title("拟合曲面") plt.show()
额外说明
- 用普通
def定义拟合函数而非lambda,是因为复杂表达式的可读性更好,也便于后续调试和修改。 curve_fit支持传入多维自变量,只要函数的第一个参数能正确解构输入的多维数据即可,这种方式是处理多自变量拟合的标准做法。
内容的提问来源于stack exchange,提问作者user26794562
相关产品推荐
相关产品推荐

