python scipy.optimize.curve_fit 使用的参数太多
我正在尝试在类实例方法中进行一些曲线拟合,并且 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 pressure drop."""
flow = coeff * pressure_drop**0.5
return flow
并且 curve_fit 函数调用
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_flow 并像这样调用它来使其工作:
spopt.curve_fit(get_flow, pressure_drop, flow)
但这不好,因为它真的需要成为类中的一种方法才能像我想要的那样具有多功能性。我怎样才能把这个工作作为类实例方法呢?
我还希望能够将 self 传递给 get_flow,以给它更多不属于 curve_fit 使用的拟合参数的参数。这可能吗?
I'm attempting to do some curve fitting within a class instance method, and the curve_fit function is giving my class instance method too many arguments.
The code is
class HeatData(hx.HX):
"""Class for handling data from heat exchanger experiments."""
then several lines of methods that work fine, then my function is:
def get_flow(pressure_drop, coeff):
"""Sets flow based on coefficient and pressure drop."""
flow = coeff * pressure_drop**0.5
return flow
and the curve_fit function call
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 )
gives the error
get_flow() takes exactly 2 arguments (3 given)
I can make it work by defining get_flow outside of the class and calling it like this:
spopt.curve_fit(get_flow, pressure_drop, flow)
but that's no good because it really needs to be a method within the class to be as versatile as I want. How can I get this work as a class instance method?
I'd also like to be able to pass self to get_flow to give it more parameters that are not fit parameters used by curve_fit. Is this possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
不幸的是,可能是 curve_fit 中的错误。 curve_fit 使用检查来确定起始值的数量,如果存在额外的
self
,则会造成混淆或误导。所以我想,给出一个起始值应该可以避免这个问题。但是,条件中还有一个 isscalar(p0) ,我不知道为什么,我认为最好将其报告为问题或错误:
编辑:避免标量作为起始值
意味着该示例仅如果起始值定义为 [...],则 1 个参数有效,例如类似于下面的示例:
具有两个参数和给定起始值的示例可以避免检查调用,并且一切都很好:
编辑:此错误已修复,因此绑定方法现在可以作为curve_fit 的第一个参数,如果您有足够新的 scipy 版本。
在 github 上提交错误修复
Unlucky case, and maybe a bug in curve_fit. curve_fit uses inspect to determine the number of starting values, which gets confused or misled if there is an extra
self
.So giving a starting value should avoid the problem, I thought. However, there is also an isscalar(p0) in the condition, I have no idea why, and I think it would be good to report it as a problem or bug:
edit: avoiding the scalar as starting value
means that the example with only 1 parameter works if the starting value is defined as [...], e.g.similar to example below:
An example with two arguments and a given starting value avoids the inspect call, and everything is fine:
EDIT: This bug has been fixed so bound methods can now be passed as the first argument for curve_fit, if you have a sufficiently new version of scipy.
Commit of bug fix submission on github
如果您在
HeatData
类中定义get_flow
,则必须将self
作为第一个参数:def get_flow(self, pressure_drop, coeff):
编辑:在寻找 curve_fit 的定义后,我 发现原型是
curve_fit(f, xdata, ydata, p0=None, sigma=None, **kw)
所以第一个arg必须是可调用的将以第一个参数作为自变量调用:尝试使用闭包:
If you define
get_flow
inside yourHeatData
class you'll have to haveself
as first parameter :def get_flow(self, pressure_drop, coeff):
EDIT: after seeking for the definition of curve_fit, i found that the prototype is
curve_fit(f, xdata, ydata, p0=None, sigma=None, **kw)
so the first arg must be a callable that will be called with first argument as the independent variable :Try with a closure :
尝试放弃“自我”并进行调用:
spopt.curve_fit(get_flow, pressure_drop, flow)
Trying dropping the "self" and making the call:
spopt.curve_fit(get_flow, pressure_drop, flow)
类方法定义的第一个参数应该始终是 self。它会自动传递并引用调用类,因此该方法总是比调用它时传递的参数多接收一个参数。
The first argument of a class method definition should always be self. That gets passed automatically and refers to the calling class, so the method always receives one more argument than you pass when calling it.
处理这个问题的唯一 Python 方法是让 Python 知道
get_flow
是一个staticmethod
:一个放入类中的函数,因为从概念上讲它属于该类,但实际上并不属于该类。需要,因此不需要self
。staticmethod
可以通过函数中未使用self
来识别。The only pythonic way to deal with this is to let Python know
get_flow
is astaticmethod
: a function that you put in the class because conceptually it belongs there but it doesn't need to be, and therefore doesn't needself
.staticmethod
's can be recognized by the fact thatself
is not used in the function.