Python-从字典中动态创建方程式



我从符合特定条件的数据库中获得的值创建了一个字典。因此,我事先既不知道字典中元素的数量,也不知道它们的值。

例如,我得到这样的东西:

ditc1 = {"P01":{"F1":0.4,"P02":0.6}, "P02":{"F2":0.3, "P03":0.7}, "P03":{"F3":0.2, "P02":0.8}}

我想做的是从以下元素动态创建数学方程:…

P01=0.4*F1+0.6*P02

P02=0.3*F2+0.7*P03

P03=0.2*F3+0.8*P02

我需要方程之间的参考保持不变(例如,第一个方程中的P02是第二个方程的P02(,这样我就可以求解那些关于P0X元素的方程。

有办法做到这一点吗?

您不必担心为变量重新创建Symbol对象。SymPy将为您创建singleton对象,每次调用Symbol('P01')时,都会返回相同的单个对象:

>>> from sympy import Symbol
>>> p = Symbol('P01')
>>> p
P01
>>> p is Symbol('P01')
True

因此,只需将您的结构直接转换为SymPy对象,SymPy就会知道P02P02 = ...等式表达式和0.6*P02乘法中都是相同的符号。

因为在嵌套字典中可能有任意数量的元素,所以可以使用sympy.Add()从任意数量的组件构建加法。我假设你也想在方程中记录=符号,所以用sympy.Eq()来表示:

from sympy import Symbol, Add, Eq
expressions = []
for p, equation_components in ditc1.items():
p = Symbol(p)
expression = []
for name, multiplier in equation_components.items():
expression.append(Symbol(name) * multiplier)
expressions.append(Eq(p, Add(*expression)))

这会产生

>>> from sympy import pprint
>>> for expr in expressions:
...     pprint(expr)
...
P₀₁ = 0.4⋅F₁ + 0.6⋅P₀₂
P₀₂ = 0.3⋅F₂ + 0.7⋅P₀₃
P₀₃ = 0.2⋅F₃ + 0.8⋅P₀₂

如果你想玩这个,这里有一个SymPy Live版本。

我只是在考虑将一个简单的符号和表达式词典转换为之类的方程列表

>>> d2e = lambda d: [*map(lambda i:Eq(*i), d.items())]
>>> d2e({x:y+1, z:2})
[Eq(x, y + 1), Eq(z, 2)]

这可以通过将字典转换为一个符号化的形式(可以通过调用Dict:来完成

>>> s = Dict(dict1)

然后,作为值出现的字典可以转换为表达式:

>>> s = {k: Add(*[s*n for s,n in v.items()]) for k,v in s.items()}; s
{P01: 0.4*F1 + 0.6*P02, P02: 0.3*F2 + 0.7*P03, P03: 0.2*F3 + 0.8*P02}

然后可以将字典转换为表达式列表;其中第一个显示为:

>>> d2e(s)[:1]
[Eq(P01, 0.4*F1 + 0.6*P02)]

(这些值可以通过像solve(d2e(s), list(s), dict=True)这样的调用来求解,以给出一个值独立于P值的字典。(

最新更新