3

亲爱的 Stackoverflow 社区,

我对 Python 和一般编程都很陌生,所以当我没有得到你的答案并再次提问时,请不要生气。

我正在尝试使用 scipy.optimization.curve_fit 将曲线拟合到实验数据。这是我的代码:

%matplotlib inline
import matplotlib.pyplot as plt
import numpy as nm
from __future__ import division
import cantera as ct
from matplotlib.backends.backend_pdf import PdfPages
import math as ma
import scipy.optimize as so


R = 8.314
T = nm.array([700, 900, 1100, 1300, 1400, 1500, 1600, 1700])
k = nm.array([289, 25695, 763059, 6358040, 14623536, 30098925, 56605969, 98832907])


def func(A, E, T):
    return A*ma.exp(-E/(R*T))
popt, pcov = so.curve_fit(func, T, k)

现在这段代码对我有用,但是如果我将函数更改为:

def func(T, A, E)

并保留我得到的其余部分:

TypeError: only length-1 arrays can be converted to Python scalars

我也不是很相信第一个参数解决方案。谁能告诉我更改变量顺序时会发生什么?

4

3 回答 3

2

我遇到了同样的问题,并找到了原因和解决方法:问题在于 Scipy 的实现。找到最佳参数后,Scipy 将输入数组xdata作为第一个参数调用您的函数。也就是说,它调用func(xdata, *args),并且该函数抱怨类型错误,因为xdata它不是标量。例如:

from math import erf
erf([1, 2]) # TypeError
erf(np.array([1, 2])) # TypeError

为避免该错误,您可以添加自定义代码以支持数组,或者更好,如 Joris 的回答中所建议,使用 numpy 函数,因为它们支持标量和数组。

如果数学函数不在 numpy 中,erf或者您编写的任何自定义函数中,那么我建议您而不是from math import erfdo ,执行以下操作:

from math import erf as math_erf # only supports scalars
import numpy as np
erf = np.vectorize(math_erf) # adds array support

def fit_func(t,s):
    return 0.5*(1.0-erf(t/(np.sqrt(2)*s)))

X = np.linspace(-5,5,1000)
Y = np.array([fit_func(x,1) for x in X])
curve_fit(fit_func, X, Y)
于 2019-10-14T17:49:46.703 回答
1

scipy 中的 curve_fit 函数不能很好地处理数学模块中的嵌入函数。当您将指数函数更改为 numpy 指数函数时,您不会收到错误消息:

def func(A, E, T):
    return A*np.exp(-E/(R*T))
于 2019-04-03T14:33:41.240 回答
0

我想知道您的数据是否显示速率呈指数衰减。数学模型可能不是最合适的模型。

在此处输入图像描述查看文档字符串curve_fit

f : callable 模型函数 f(x, ...)。它必须将自变量作为第一个参数,并将要拟合的参数作为单独的剩余参数。

因为你的公式本质上是:k=A*ma.exp(-E/(R*T)),参数的正确顺序func应该是(T, A, E)(T, E, A)

关于 and 的顺序AE它们并不重要。如果你翻转它们,结果也会被翻转:

>>> def func(T, A, E):
    return A*ma.exp(-E/(R*T))

>>> so.curve_fit(func, T, k)
(array([  8.21449078e+00,  -5.86499656e+04]), array([[  6.07720215e+09,   4.31864058e+12],
       [  4.31864058e+12,   3.07102992e+15]]))
>>> def func(T, E, A):
    return A*ma.exp(-E/(R*T))

>>> so.curve_fit(func, T, k)
(array([ -5.86499656e+04,   8.21449078e+00]), array([[  3.07102992e+15,   4.31864058e+12],
       [  4.31864058e+12,   6.07720215e+09]]))

我根本没有得到你typeerror的。

于 2013-09-30T04:38:55.553 回答