scipy 的 curve_fit 函数的维度问题
Dimension issue with scipy's curve_fit function
我不熟悉 python 中的曲线拟合,一般来说 python 也是如此。目前,我正在尝试使用 scipy 中的 curve_fit 模块来拟合 4 个光谱峰。
简而言之,我在一个包含两列的文本文件中有数据。所以我的第一步是将数据导入两个数组,一个包含 xdata,另一个包含 y 数据。然后我尝试定义我要拟合的函数(四个 voigt 峰)。最后,当我尝试 运行 整个事情时,出现以下错误:
raise TypeError('Improper input: N=%s must not exceed M=%s' % (n, m)) TypeError: Improper input: N=11 must not exceed M=1
据我从 curve_fit help 页面可以看出,这个错误表明我必须至少有与拟合参数一样多的数据点,这是有道理的。问题是我的数据集里面有250个点...
这是我的代码
import numpy as n
import pyspec as p
from scipy.optimize import curve_fit
file = open('fileName', "r") #open the file
data = n.loadtxt(file) #load the file into an array
freq = n.array(data[:, 0] - n.median(data[:, 0])) #center data on zero.
counts = n.array(data[:, 1])
error = n.array(data[:, 1]**0.5) #get the error on the counts. Standard poisson error.
# Define a single voigt profile
def voigt(xdata, amp, cent, FWHM, ep) :
x = xdata
C = cent
F = FWHM
A = amp
E = ep
vmodel = A * ((1 - E)*n.exp(-2.77259 * (n.square(x - C))/n.square(F)) + E / (1 + (4 * n.square(x - C)/F**2)))
return[vmodel]
#Define the four peak function
def voigt4(xdata, amp1, amp2, amp3, amp4, pos1, pos2, pos3, pos4, FWHM, ep, Bg):
voigtp1 = voigt(xdata, amp1, pos1, FWHM, ep)
voigtp2 = voigt(xdata, amp2, pos2, FWHM, ep)
voigtp3 = voigt(xdata, amp3, pos3, FWHM, ep)
voigtp4 = voigt(xdata, amp4, pos3, FWHM, ep)
voigt4 = (voigtp1 + voigtp2 + voigtp3 + voigtp4 + Bg) # include a background term
return[voigt4]
# give an initial guess. The *_in params are initial guesses made by the user.
guess = n.array([amp1_in, amp2_in, amp3_in, amp4_in, pos1_in, pos2_in, pos3_in, pos4_in, 500, 0.5, bkgr_in])
fit = curve_fit(voigt4, freq, counts, guess) # try to fit
我不知道为什么会出现这个错误。
如评论中所述,您应该删除函数 voigt
和 voigt4
中 return 语句中的括号。括号的问题是您将要 return 的数组放在列表中,从而减少了 returned 对象的尺寸。考虑以下示例:
import numpy as np
ar = np.array([1, 2, 3, 4])
然后命令
len(ar)
会 return 4 和
a[0]
returns 1 如预期。如果你现在做
b = [ar]
正如您在 return 声明中所做的那样
b
会是
[array([1, 2, 3, 4])]
和
b[0]
不再是单个值,而是整个原始数组:
array([1, 2, 3, 4])
这意味着您收到了类似
的错误
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-269-33e961e0e4ea> in <module>()
----> 1 b[1]
IndexError: list index out of range
如果您尝试访问 b[1]
。
因此,当您将多维对象缩减为一维对象时,收到有关维度的错误消息也就不足为奇了。
我不熟悉 python 中的曲线拟合,一般来说 python 也是如此。目前,我正在尝试使用 scipy 中的 curve_fit 模块来拟合 4 个光谱峰。
简而言之,我在一个包含两列的文本文件中有数据。所以我的第一步是将数据导入两个数组,一个包含 xdata,另一个包含 y 数据。然后我尝试定义我要拟合的函数(四个 voigt 峰)。最后,当我尝试 运行 整个事情时,出现以下错误:
raise TypeError('Improper input: N=%s must not exceed M=%s' % (n, m)) TypeError: Improper input: N=11 must not exceed M=1
据我从 curve_fit help 页面可以看出,这个错误表明我必须至少有与拟合参数一样多的数据点,这是有道理的。问题是我的数据集里面有250个点...
这是我的代码
import numpy as n
import pyspec as p
from scipy.optimize import curve_fit
file = open('fileName', "r") #open the file
data = n.loadtxt(file) #load the file into an array
freq = n.array(data[:, 0] - n.median(data[:, 0])) #center data on zero.
counts = n.array(data[:, 1])
error = n.array(data[:, 1]**0.5) #get the error on the counts. Standard poisson error.
# Define a single voigt profile
def voigt(xdata, amp, cent, FWHM, ep) :
x = xdata
C = cent
F = FWHM
A = amp
E = ep
vmodel = A * ((1 - E)*n.exp(-2.77259 * (n.square(x - C))/n.square(F)) + E / (1 + (4 * n.square(x - C)/F**2)))
return[vmodel]
#Define the four peak function
def voigt4(xdata, amp1, amp2, amp3, amp4, pos1, pos2, pos3, pos4, FWHM, ep, Bg):
voigtp1 = voigt(xdata, amp1, pos1, FWHM, ep)
voigtp2 = voigt(xdata, amp2, pos2, FWHM, ep)
voigtp3 = voigt(xdata, amp3, pos3, FWHM, ep)
voigtp4 = voigt(xdata, amp4, pos3, FWHM, ep)
voigt4 = (voigtp1 + voigtp2 + voigtp3 + voigtp4 + Bg) # include a background term
return[voigt4]
# give an initial guess. The *_in params are initial guesses made by the user.
guess = n.array([amp1_in, amp2_in, amp3_in, amp4_in, pos1_in, pos2_in, pos3_in, pos4_in, 500, 0.5, bkgr_in])
fit = curve_fit(voigt4, freq, counts, guess) # try to fit
我不知道为什么会出现这个错误。
如评论中所述,您应该删除函数 voigt
和 voigt4
中 return 语句中的括号。括号的问题是您将要 return 的数组放在列表中,从而减少了 returned 对象的尺寸。考虑以下示例:
import numpy as np
ar = np.array([1, 2, 3, 4])
然后命令
len(ar)
会 return 4 和
a[0]
returns 1 如预期。如果你现在做
b = [ar]
正如您在 return 声明中所做的那样
b
会是
[array([1, 2, 3, 4])]
和
b[0]
不再是单个值,而是整个原始数组:
array([1, 2, 3, 4])
这意味着您收到了类似
的错误---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-269-33e961e0e4ea> in <module>()
----> 1 b[1]
IndexError: list index out of range
如果您尝试访问 b[1]
。
因此,当您将多维对象缩减为一维对象时,收到有关维度的错误消息也就不足为奇了。