TypeError:'numpy.ndarray'对象在scipy.optimize leastsq中不可调用

时间:2016-03-26 14:57:46

标签: python macos numpy

我是Python的新手,出于工作原因,我正在尝试编写一个能够读取包含float(x,y)数据的三个文件的Python代码(比方说x1,y1; x2,y2; x3, y3)并将两个阵列(y1和y2)与线性组合相结合,尽可能接近第三个(y3)。此外,x1和x2是相同的,而x3是不同的,所以我使用x1插入x3和y3。我正在研究Mac OSX上的Idle和Python 2.7。 这是我的代码:

import numpy as np
import matplotlib.pyplot as plt
import Tkinter as tk
import tkFileDialog
from scipy.optimize import leastsq

root1 = tk.Tk()
root1.geometry() #window centered on desktop?
root1.withdraw() #the main app window doesn't remain in the background
filename1 = tkFileDialog.askopenfilename(parent=root1, title="Ouvrir le spectre n° 1",
    filetypes=[('dat files', '.dat'), ('all files', '.*')],
    initialdir="/Users//Science/Manips/2011_10_05_Nb_W/")
filename2 = tkFileDialog.askopenfilename(parent=root1,title="Ouvrir le spectre n° 2",
    filetypes=[('dat files', '.dat'), ('all files', '.*')],
    initialdir="/Users/Science/Manips/2011_10_05_Nb_W/")
filenameexp = tkFileDialog.askopenfilename(parent=root1, title="Ouvrir le spectre exp",
    filetypes=[('txt files', '.txt'), ('all files', '.*')],
    initialdir="/Users/Science/Manips/2011_10_05_Nb_W/spectres_exp")

print 'Fichiers choisis = '
print filename1
print filename2
print filenameexp

energy1, spectrum1 = np.loadtxt(filename1, delimiter='   ', usecols=(0, 1),
                            unpack=True, skiprows=0)
energy2, spectrum2 = np.loadtxt(filename2, delimiter='   ', usecols=(0, 1),
                            unpack=True, skiprows=0)
energyexp, spectrumexp = np.loadtxt(filenameexp, delimiter='\t', usecols=(0, 1),
                            unpack=True, skiprows=0)

#Interpolating experimental energy grid on theoretical energy grid
sp_exp_int = np.interp(energy1, energyexp, spectrumexp)

#guess contains the first guess of the parameters 
guess=[1.0,1.0]
spec_theo = guess[0] * spectrum1 + guess[1] * spectrum2

# ErrorFunc is the difference between the "fit" and the y experimental data
ErrorFunc = spec_theo - sp_exp_int
# leastsq finds the set of parameters in the tuple tpl that minimizes
# ErrorFunc=yfit-yExperimental
tplFinal, success = leastsq(ErrorFunc, guess[:], args=(energy1, sp_exp_int))
print "best choice = ", tplFinal

fig, ax1 = plt.subplots()
theory = ax1.plot(energy1, spec_theo, 'b-', label='Theory')
ax1.set_xlabel('Energy (eV)')
# Make the y-axis label and match the line color.
ax1.set_ylabel('Theory', color='b')

ax2 = ax1.twinx()
experiment = ax2.plot(energy1, sp_exp_int, 'r-', label='Experiment')
ax2.set_ylabel('Experiment', color='r', rotation=-90, labelpad=15)

#one legend for all axes
lns = theory + experiment
labs = [l.get_label() for l in lns]
ax1.legend(lns, labs, loc=0)

plt.show()

当我尝试运行代码时,我得到了:

Traceback (most recent call last):
 File "/Users/Science/Manips/2011_05_Nb_W/Mars2016/comblin_leastsquares.py", line 79, in <module>
tplFinal, success = leastsq(ErrorFunc, guess[:], args=(energy1, sp_exp_int))
File   "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site- packages/scipy/optimize/minpack.py", line 377, in leastsq
shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/scipy/optimize/minpack.py", line 26, in _check_func
res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
TypeError: 'numpy.ndarray' object is not callable

我理解我的最小用法有问题,但我真的无法弄清楚它是什么,我对Python的了解显然是不够的。 有人能帮助我吗?

2 个答案:

答案 0 :(得分:2)

错误清楚地说明了错误:您传递的是数组而不是函数/可调用数据。事实上,leastsq文档指出第一个参数应该是可调用

您正在传递ErrorFunc作为第一个参数,但这是一个函数,也不是可调用的。它是一个阵列。 (它可能表示一个函数,但它不是leastsq所需的格式。

所以你必须遵循参数的描述:

  

应该至少使用一个(可能是N}个向量)参数   返回M个浮点数。它不能返回NaN或拟合   可能会失败。

所以用一个callable替换ErrorFunc,给定输入将错误返回为浮点数。基本上你应该有:

def error_func(input):
    return input - data

data是您的实验数据,inputscipy正在进行的拟合的值。它需要一个可调用的,因为它将执行更多的迭代,并且对于每次迭代,它必须计算错误以适应数据。

显然更改error_func以匹配您正在执行的操作,这只是为了了解leastsq所期望的内容。

答案 1 :(得分:0)

以防它可以帮助其他人,我已经使代码适用于:

<same code as in my question>
#guess contains the first guess of the parameters 
guess=[1.0,1.0]

# error_func is the difference between the "fit" and the y experimental data
#error_func = spec_theo - sp_exp_int
def error_func(coeff, sp1, sp2, y):
    return (coeff[0] * sp1 + coeff[1] * sp2) - y

# leastsq finds the set of parameters in the tuple tpl that minimizes
# error_func=yfit-yExperimental
guess_fin, success = leastsq(error_func, guess[:], args=(spectrum1, \
                            spectrum2, sp_exp_int))
print 'best choice = ', guess_fin
print 'success = ', success

spec_theo = guess_fin[0] * spectrum1 + guess_fin[1] * spectrum2

fig, ax1 = plt.subplots()
...

谢谢Bakuriu!