You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

scipy.optimize.curve_fit为何无法将列表作为单个参数传入p0?

解决scipy.optimize.curve_fit参数不匹配报错问题

问题根源

curve_fit的工作逻辑是将p0中的每个元素作为独立参数传递给拟合函数。你传入嵌套列表p0=[[1, 0.1, 1, 640, 1, 0.2, 651, 2]]时,它会把内层的8个元素拆成8个独立参数,加上输入x后,一共9个参数传给你的gauss函数,但你的函数只接受2个参数(x和peaks列表),因此触发TypeError。

两种解决方案

方案1:修改自定义函数,接受可变数量的独立参数

直接调整gauss函数的参数定义,用*params接收所有独立参数,再在函数内部将参数重组为你需要的峰结构:

import numpy as np
from scipy.optimize import curve_fit

def gauss(x, *params):
    # 将扁平化的参数重组为峰列表(假设每个峰对应4个参数:振幅、宽度、偏移、中心)
    peaks = np.array(params).reshape(-1, 4)
    y = np.zeros_like(x)
    for amp, width, offset, center in peaks:
        y += amp * np.exp(-(x - center)**2 / (2 * width**2)) + offset
    return y

# 生成测试数据
x = np.linspace(600, 700, 100)
y_true = 1*np.exp(-(x-640)**2/(2*0.1**2)) + 1 + 1*np.exp(-(x-651)**2/(2*0.2**2)) + 2
y_noise = y_true + 0.05*np.random.normal(size=x.size)

# 初始参数直接传扁平化列表,无需嵌套
p0 = [1, 0.1, 1, 640, 1, 0.2, 651, 2]
popt, pcov = curve_fit(gauss, x, y_noise, p0=p0)

print("拟合后的峰参数:", popt.reshape(-1, 4))

方案2:用lambda包装函数,保留原函数参数结构

如果不想修改原gauss函数的参数定义,可以用lambda表达式将curve_fit传递的多个独立参数打包成列表,再传给原函数:

import numpy as np
from scipy.optimize import curve_fit

# 原自定义高斯函数,保持接收x和单个peaks参数
def gauss(x, peaks):
    y = np.zeros_like(x)
    peaks = np.array(peaks).reshape(-1, 4)
    for amp, width, offset, center in peaks:
        y += amp * np.exp(-(x - center)**2 / (2 * width**2)) + offset
    return y

# 生成测试数据
x = np.linspace(600, 700, 100)
y_true = 1*np.exp(-(x-640)**2/(2*0.1**2)) + 1 + 1*np.exp(-(x-651)**2/(2*0.2**2)) + 2
y_noise = y_true + 0.05*np.random.normal(size=x.size)

# 用lambda打包参数,p0传扁平化列表
p0 = [1, 0.1, 1, 640, 1, 0.2, 651, 2]
popt, pcov = curve_fit(lambda x, *p: gauss(x, p), x, y_noise, p0=p0)

print("拟合后的峰参数:", np.array(popt).reshape(-1, 4))

内容的提问来源于stack exchange,提问作者mrecksie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 11:10:37