假设我有以下函数(非常简单,用来解释问题的要点):

def func(a=None, b=None, c=None):    
    return 100-(a+b*c)

此函数的最终目的是在已知其他两个参数(例如结果等于0)的情况下找到根,即对一个参数进行求解.

如果我想使用Scipy的fsolve函数来求解a,当bc已知时,这不是问题:

>>> 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是未知的),但在我看来这不是一种非常有效的方法.此外,我将来可能会遇到类似的问题,因为函数的参数比这个多得多.

当然,单个参数可以设置为None,但我单独处理这个问题,所以我们可以假设始终有一个未知值--唯一的问题是,这个未知值的参数可以是任何一个参数.我希望能够"告诉"Scipy求解这None个值,无论它的参数位于什么位置.

推荐答案

我们将定义一个名为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)

Python相关问答推荐

如何将Pydantic URL验证限制为特定主机或网站

从多行文本中提取事件对

如何将自动创建的代码转换为类而不是字符串?

合并其中一个具有重叠范围的两个框架的最佳方法是什么?

使用Python Great Expectations和python-oracledb

使用Python C API重新启动Python解释器

如何知道标志是否由用户传递或具有默认值?

收件箱转换错误- polars.exceptions. ComputeHelp- pandera(0.19.0b3)带有polars

Odoo -无法比较使用@api.depends设置计算字段的日期

比较2 PD.数组的令人惊讶的结果

Pandas - groupby字符串字段并按时间范围 Select

如何制作10,000年及以后的日期时间对象?

如何使用根据其他值相似的列从列表中获取的中间值填充空NaN数据

在Wayland上使用setCellWidget时,try 编辑QTable Widget中的单元格时,PyQt 6崩溃

如何从.cgi网站刮一张表到rame?

如何创建一个缓冲区周围的一行与manim?

如果初始groupby找不到满足掩码条件的第一行,我如何更改groupby列,以找到它?

如何在BeautifulSoup/CSS Select 器中处理regex?

如何防止Pandas将索引标为周期?

如何使用OpenGL使球体遵循Python中的八样路径?