问题描述
如何最好地返回具有动态变量名称的函数? 通常应该避免它。 但是由于外部包的限制,这可能并不总是可行的。例如。 LMFit 使用显式变量名称来处理模型的参数。
如果函数是
def (x,y):
return y*x
然后需要通过参数的显式名称 y
来寻址。
对于复杂的通用拟合模型,可能需要动态生成具有不同参数的模型,例如:
def make_model(x,myDict):
...
def myModel(x,V1,V2):
...
...
return result
return myModel
在本例中,我想将变量 V1
和 V2
的名称更改为例如myDict
的键。这可能吗?是否应该这样做,如果不这样做,我该如何创建一个具有可交换变量名称的函数以在此类包中使用?
我不想让它们被称为 V1
和 V2
,因为在稍后处理它们时(并且当参数大于 5 时),跟踪用户的名称可能很笨拙。>
解决方法
这可能吗?
简短的回答是“不”。 lmfit.Model
类检查模型函数以确定参数名称。这是一个对用户有利的重要特性:参数应该被命名,而不是按照某种语法上重要但语义上毫无意义的顺序放置。
您可以使用 scipy.optimize.curve_fit
之类的东西。为此,变量从具有属性的参数对象减少到浮点值,这些浮点值必须处于一致但最终毫无意义的顺序。避免使用curve_fit
还有其他原因,但是这种对“拟合参数”的糟糕抽象真的很不幸——就像作者忘记了他们在使用 Python 并认为他们正在编写 Fortran77。
或者您可以使用 lmfit.minimize
并编写自己的目标函数(对于曲线拟合,只需返回“(数据模式)/不确定性”)。使用该接口,您传递一个 lmfit.Parameters
对象 - 本质上是一个(有序的)Parameter 对象字典,然后您将其解压到您的目标函数中。
是否应该这样做,如果不这样做,
我会说“可能不是”,并且您不应将参数命名为 V1
、V2
等,除非这对您和处理结果的人员有意义。如果你告诉我 V1
是 100.2 而 V2
是 0.75,我会说“哦,好吧...”。 OTOH,如果你告诉我 Volume1
是 100.2 而 Velocity2
是 0.75,现在我开始明白了。名字很重要。
我还能如何创建具有可交换变量名称的函数以在此类包中使用?
使用命名参数构建函数,然后跟踪它们。