python scipy.optimize.curve\u fit使用的参数太多
我试图在类实例方法中进行一些曲线拟合,而curve_fit函数给了我的类实例方法太多的参数 代码是python scipy.optimize.curve\u fit使用的参数太多,python,scipy,curve-fitting,Python,Scipy,Curve Fitting,我试图在类实例方法中进行一些曲线拟合,而curve_fit函数给了我的类实例方法太多的参数 代码是 class HeatData(hx.HX): """Class for handling data from heat exchanger experiments.""" 然后是几行工作正常的方法,然后我的功能是: def get_flow(pressure_drop, coeff): """Sets flow based on coefficient and p
class HeatData(hx.HX):
"""Class for handling data from heat exchanger experiments."""
然后是几行工作正常的方法,然后我的功能是:
def get_flow(pressure_drop, coeff):
"""Sets flow based on coefficient and pressure drop."""
flow = coeff * pressure_drop**0.5
return flow
以及曲线拟合函数调用
def set_flow_array(self):
"""Sets experimental flow rate through heat exchanger"""
flow = self.flow_data.flow
pressure_drop = self.flow_data.pressure_drop
popt, pcov = spopt.curve_fit(self.get_flow, pressure_drop, flow)
self.exh.flow_coeff = popt
self.exh.flow_array = ( self.exh.flow_coeff * self.exh.pressure_drop**0.5 )
给出了错误
get_flow() takes exactly 2 arguments (3 given)
我可以通过在类外定义get_流并这样调用它来实现它:
spopt.curve_fit(get_flow, pressure_drop, flow)
但这并不好,因为它确实需要成为类中的一个方法,才能像我所希望的那样具有多功能。如何将此工作作为类实例方法进行
我还希望能够通过self来获得更多的参数,这些参数不是曲线拟合所使用的拟合参数。这可能吗?如果在
HeatData
类中定义get\u flow
,则必须将self
作为第一个参数:def get\u flow(self、压降、系数):
编辑:在寻找曲线拟合的定义后,icurve\u fit(f,xdata,ydata,p0=None,sigma=None,**kw)
因此第一个参数必须是一个可调用的参数,将第一个参数作为自变量调用:
尝试关闭:
def set_flow_array(self):
"""Sets experimental flow rate through heat exchanger"""
flow = self.flow_data.flow
pressure_drop = self.flow_data.pressure_drop
def get_flow((pressure_drop, coeff):
"""Sets flow based on coefficient and pressure drop."""
#here you can use self.what_you_need
# you can even call a self.get_flow(pressure_drop, coeff) method :)
flow = coeff * pressure_drop**0.5
return flow
popt, pcov = spopt.curve_fit(get_flow, pressure_drop, flow)
self.exh.flow_coeff = popt
self.exh.flow_array = ( self.exh.flow_coeff * self.exh.pressure_drop**0.5 )
尝试删除“self”并进行调用:
spopt.curve\u fit(get\u flow,pressure\u drop,flow)
类方法定义的第一个参数应该始终是self。它会自动传递并引用调用类,因此该方法在调用时总是比您传递的多接收一个参数。不幸的情况,可能是曲线拟合中的错误。曲线拟合使用inspect来确定起始值的数量,如果存在额外的self
,则会产生混淆或误导
@staticmethod
def get_flow(pressure_drop, coeff):
"""Sets flow based on coefficient and pressure drop."""
flow = coeff * pressure_drop**0.5
return flow
所以我想,给出一个起始值应该可以避免这个问题。然而,在这种情况下也有一个isscalar(p0),我不知道为什么,我认为最好将其作为问题或bug报告:
if p0 is None or isscalar(p0):
# determine number of parameters by inspecting the function
import inspect
args, varargs, varkw, defaults = inspect.getargspec(f)
编辑:避免将标量作为起始值
>>> np.isscalar([2])
False
表示如果起始值定义为[…],则只有1个参数的示例有效,例如,类似于下面的示例:
mc.optimize([2])
具有两个参数和给定起始值的示例避免了inspect调用,一切正常:
import numpy as np
from scipy.optimize import curve_fit
class MyClass(object):
def get_flow(self, pressure_drop, coeff, coeff2):
"""Sets flow based on coefficient and pressure drop."""
flow = coeff * pressure_drop**0.5 + coeff2
return flow
def optimize(self, start_value=None):
coeff = 1
pressure_drop = np.arange(20.)
flow = coeff * pressure_drop**0.5 + np.random.randn(20)
return curve_fit(self.get_flow, pressure_drop, flow, p0=start_value)
mc = MyClass()
print mc.optimize([2,1])
import inspect
args, varargs, varkw, defaults = inspect.getargspec(mc.get_flow)
print args, len(args)
编辑:此错误已修复,因此绑定方法现在可以作为曲线拟合的第一个参数传递,如果您有足够新版本的scipy。处理这个问题的唯一Python方法是让Python知道
get\u flow
是一个staticmethod
:一个函数,你把它放在类中,因为概念上它属于类,但它不需要,因此不需要self
@staticmethod
def get_flow(pressure_drop, coeff):
"""Sets flow based on coefficient and pressure drop."""
flow = coeff * pressure_drop**0.5
return flow
staticmethod
可以通过函数中未使用self
这一事实来识别。我尝试过,然后错误是get\u flow()正好取3个参数(给定4个)
在调用curve\u fit(self.get\u flow,self,…)时尝试添加self作为参数当前,我得到了def get\u flow(self,压降,系数):
和spopt.curve\u fit(self.get\u flow,pressure\u drop,flow)
这仍然会产生错误get\u flow()只需要3个参数(4个给定)
如果调用spopt.curve\u fit(self.get\u flow,self,pressure\u drop,flow)
?这个主意很酷,但它就是这样做的:get\u flow()只需要2个参数(给定16个)
如果get\u flow被定义为一个HeatData方法,那么我通过删除self得到以下错误:全局名称“get\u flow”没有定义
我想我只需要一种方法来调用get\u flow而不调用self引用,这显然是为绑定方法自动完成的,无论“self”是否作为参数传递。有点奇怪/酷的是,“self”一词只是一个约定,我可以用“hornswagle”一词代替self。我想这不是一个非常描述性的编码实践。太好了!我现在这样运行:popt,pcov=spopt.curve\u fit(self.get\u flow,pressure\u drop,flow,p0=np.array([self.exh.flow\u coeff])
并且它工作得很好。我同意这是一个错误,因为如果我给p0一个值,它应该使用它来确定参数的数量,即使p0是一个标量。