Python/curve_fit:无法通过初始化猜测传递数组

Posted

技术标签:

【中文标题】Python/curve_fit:无法通过初始化猜测传递数组【英文标题】:Python/curve_fit: cannot pass array with init guess 【发布时间】:2019-07-25 06:37:23 【问题描述】:

我有这个函数来计算某种多项式:

def pipoly(df,pj):
    n=np.size(pj)
    p=pj[0]
    for j in range(1,n):
        p+=pj[j]*df**j
    return p

pj 应该是一个包含多项式系数的初始猜测的数组;因此,多项式的次数由第一行中的函数本身决定。 df 是一个标量变量。这个函数传递给scipy.optimize的curve_fit as

parfit,covfig=curve_fit(pipoly,[f-f0[j] for f in f_df[if0[j]:if0[i]]],
                            pmode_xp[ph][if0[j]:if0[i]],
                            p0=([pmode0[ph][-1],(pmode_xp[ph][if0[i]]-pmode_xp[ph][if0[j]])/df]))

函数名称后的前两个参数是数组(二维数组的一维切片),我已经确认它们的长度相同。 pipoly 之后的第三个参数应该是一个元组,其中包含 pj 的初始猜测,我之前打印出来:[0.4586590267346888, 0.7419930843896957]。那么为什么 Python 会抱怨 TypeError: pipoly() takes 2 positional arguments but 3 were given 呢?如果我删除 p0 参数,我会被告知 pj 被认为是标量,因此不能有索引。如何让 pipoly 清楚 pj 是一个数组?

【问题讨论】:

【参考方案1】:

您的陈述:

pj 应该是一个包含 多项式;

错了。根据curve_fit() docs:

scipy.optimize.curve_fit(f, xdata, ydata, p0=None, sigma=None, absolute_sigma=False, check_finite=True, bounds=(-inf, inf), method=None, jac=None, ** kwargs)[来源] 使用非线性最小二乘法将函数 f 拟合到数据。

假设 ydata = f(xdata, *params) + eps

这意味着 curve_fit() 使用的 pipoly() 函数必须接受的参数数量等于多项式的参数数量加一(变量,即第一个参数)。 错误:

TypeError: pipoly() 接受 2 个位置参数但给出了 3 个?

告诉您pipoly 接收 3 个参数,因为您可能正在测试线性多项式,所以这三个参数是自变量和两个参数([f-f0[j] for f in f_df[if0[j]:if0[i]]] 的东西是一个 2 长度的列表)。 当你写它时,它只需要 2 个参数。

您可以通过在pj前添加星号轻松解决您的问题:

def pipoly(df,*pj):
    n=len(pj) #len() is sufficient here, but np.size() works too.
    p=pj[0]
    for j in range(1,n):
        p+=pj[j]*df**j
    return p

这样你的函数接受可变数量的参数。 Here更多关于python函数参数中星号的含义和使用。

【讨论】:

我已经编辑了我的帖子,以澄清 pj 应该包含参数(即系数)的 初始猜测。是的,在示例中,我正在尝试使用线性函数。但是,如果我按照您的建议更改 pipoly 的定义,则结果不是所需的单个数字,而是一个序列。 这也是不正确的。它只是表示要估计其值的多项式的参数。您在curve_fit()p0)中提供了最初的猜测。是的,结果是一个包含参数估计值的序列。为什么你期望结果是一个数字? pipoly 是拟合模型,它应该为每个df 返回一个值。换句话说,当curve_fitparfit 中产生一组参数作为拟合的结果时,我应该能够在像pipoly(0.2,parfit) 这样的调用中传递这些参数,以便pipoly 的函数值为0.2根据优化后的参数集返回。 因为你没有解压参数列表。试试这个:y = pipoly(0.2, *parfit)(再次注意星号。阅读我的答案中的链接)。 y 是您的预期结果。

以上是关于Python/curve_fit:无法通过初始化猜测传递数组的主要内容,如果未能解决你的问题,请参考以下文章

python猜数字GUI版本V0.2

猜数字游戏的实现(Python3.5)

猜数字游戏程序无法正常运行

JavaScript一个猜数字游戏

通过游戏学python 3.6 第一季 第三章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释 可复制直接使用 娱乐 可封装 函数

猜数字游戏