提问人:J-J-J 提问时间:10/10/2023 最后编辑:J-J-J 更新时间:10/10/2023 访问量:53
scipy 优化:如何让它与只有可选参数的函数一起工作?
scipy optimize: how to make it work with a function that has only optional arguments?
问:
假设我有以下功能(非常简化,以解释问题的要点):
def func(a=None, b=None, c=None):
return 100-(a+b*c)
此函数的目的是最终找到根,即求解一个参数,而其他两个参数是已知的,例如结果等于 0。
如果我想使用 scipy 的 fsolve 函数来求解 , when 和 are known,这不是问题:a
b
c
>>> from scipy import optimize
>>> dat = {"b":1, "c":2}
>>> optimize.fsolve(lambda x: func(x, **dat), x0=0)
array([98.])
如果我想求解任何不在第一个位置的参数(例如),它就会成为一个问题:c
>>> dat = {"a":1, "b":2}
>>> optimize.fsolve(lambda x: func(x, **dat), x0=0)
TypeError: func() got multiple values for argument 'a'
我想一个解决方案是将具有值的参数设置为固定的“第一个位置”参数,但我不知道该怎么做,或者是否可能。None
当然,“愚蠢”的解决方案是创建三个不同的函数来考虑所有可能的用例(何时未知、何时未知以及何时未知),但对我来说,这似乎不是一个非常有效的方法。此外,我将来可能会遇到类似的问题,因为函数的参数比这多得多。a
b
c
当然,可以设置一个参数,但我单独处理这个问题,所以我们可以假设总是有一个未知值 - 唯一的问题是这个具有未知值的参数可以是任何一个参数。我希望能够“告诉”scipy求解这个值,无论其参数的位置如何。None
None
答:
2赞
Seon
10/10/2023
#1
我们将定义一个名为 的函数,它接受一个函数和一个你希望冻结的关键字参数的字典。然后,它将返回一个新函数,该函数将剩余的关键字参数作为位置参数。get_partial
functools.partial
在这里不能完全完成工作:它确实允许您冻结除一个关键字参数之外的所有关键字参数,但它不会将最后一个关键字参数转换为位置参数。
import inspect
from scipy import optimize
def get_partial(f, fixed_kwargs):
all_kwargs = inspect.signature(f).parameters.keys()
bound_kwargs = fixed_kwargs.keys()
free_kwarg = (all_kwargs - bound_kwargs).pop()
return lambda x: f(**(fixed_kwargs | {free_kwarg: x}))
def func(a=None, b=None, c=None):
return 100 - (a + b * c)
dat = {"a": 1, "b": 2}
optimize.fsolve(get_partial(func, dat), x0=0)
评论
0赞
J-J-J
10/10/2023
感谢您抽出宝贵时间回答。我不确定 in 来自哪里,它会抛出“名称'f'未定义”错误。如果我用 替换它,我会得到与之前相同的错误(“func() 为参数 'a' 获得了多个值”)。值得一提的是,我使用 Python 3.10.2 和 scipy 1.10.1。f
partial(f, **dat)
func
1赞
Seon
10/10/2023
我最初的答案根本不起作用,我已经完全重写了它。
0赞
J-J-J
10/10/2023
太棒了,感谢您抽出宝贵时间对此进行调查!
上一个:“未知命名参数”难以理解的错误
评论