2016-01-18 48 views
3

我是新来的python的曲线拟合,以及一般的python。目前,我正尝试使用scipy中的curve_fit模块来适应4个光谱峰。scipy的curve_fit函数的尺寸问题

简而言之,我有一个文本文件中有两列的数据。所以我的第一步是将数据导入两个数组,一个包含xdata,另一个包含y数据。然后我试着定义我将要适合的功能(四个峰值峰值)。最后,当我试图运行整个事情,我得到以下错误:

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 

我不知道为什么这个错误出现。

+1

尝试删除返回语句中的括号。例如。 'return vmodel'和'return voigt4'。 –

+0

我同意@WarrenWeckesser:删除你的返回语句中的括号,看看它是否已经解决了这个问题。总的来说:如果你发布了你使用的数据,这也会很好,这有助于运行代码并解决问题。 – Cleb

+0

这工作完美!非常感谢您的答复和建议,如果我遇到其他问题,我一定会发布数据。你介意解释为什么括号是问题吗? –

回答

1

正如评论中所写,您应该删除函数voigtvoigt4中返回语句的括号。括号中的问题是您将要返回的数组放入列表中,从而减少返回对象的尺寸。考虑下面的例子:

import numpy as np 
ar = np.array([1, 2, 3, 4]) 

然后命令

len(ar) 

将返回4点

a[0] 

返回1按预期方式。如果你现在要做的

b = [ar] 

,你在你的回报声明没有

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]

因此,由于您将多维对象缩小为一维对象,因此您会收到有关维度的错误消息并不是一个大惊喜。

+0

是的,这个答案完全是我的问题。顺便说一句,这也可能有助于我遇到的另一个问题。再次感谢! –

+0

@JulienRefour:很高兴它解决了这个问题!与其他问题祝你好运! – Cleb