Python使用scipy.curve_fit拟合自定义函数触发TypeError报错如何解决
报错原因
你自定义的拟合函数sinugauss返回值形状不符合scipy.optimize.curve_fit的要求:
- 你传入的
datos['x']是长度为33的一维数组,函数内部计算得到的Ventas/(np.exp(exponente))本来也是长度为33的一维数组,但是你额外套了一层方括号,再通过np.array()转换后,返回值变成了形状为(1, 33)的二维数组。 curve_fit会将这个二维数组识别为长度为1的输出序列,而你有3个待拟合参数,拟合逻辑要求输出序列长度必须大于等于待拟合参数数量,因此触发N=3 > M=1的类型错误。
解决方法
- 首先修改拟合函数的返回值,删除多余的方括号包装,保证返回和输入x长度一致的一维数组:
def sinugauss(x, Ventas, Inicio, Desv): exponente = Desv*(np.sin(x-Inicio))**2 # 去掉外层方括号,直接返回计算结果即可,numpy运算结果本身就是数组 return Ventas / np.exp(exponente)
- 建议给
curve_fit传入合理的初始参数猜测值p0,非线性拟合对初始值敏感,缺省初始值全为1很容易出现拟合发散、结果不符合预期的问题,可根据你的数据业务含义自行调整初始值,示例:
# 示例初始值,可根据你的实际数据范围修改 res, cov = curve_fit(sinugauss, datos['x'], datos['y'], p0=[10, 0, 0.5])
- 可选优化:如果后续拟合还出现数值问题,可检查输入x的取值范围,避免sin的参数过大导致震荡,同时如果y存在零值,可根据实际情况添加极小的偏移量避免数值溢出。
内容的提问来源于stack exchange,提问作者Alejandro Salazar
相关产品推荐
相关产品推荐

