簡體   English   中英

將 sympy 中命名表達式的字符串轉換為表達式本身

[英]Convert string of a named expression in sympy to the expression itself

實際問題描述
我已經使用sympy定義了許多表達式,如

import sympy as sp
a, b = sp.symbols('a,b', real=True, positive=True)
Xcharles_YclassA_Zregion1 = 1.01 * a**1.01 * b**0.99
Xbob_YclassA_Zregion1 = 1.009999 * a**1.01 * b**0.99
Xbob_YclassA_Zregion2 = 1.009999 * a**1.01 * b**0.99000000001
...

所以我使用表達式的名稱來描述類別(例如X )中的選項(例如charlesbob )。

現在我想要一個 function 接受兩個字符串(例如, 'Xcharles_YclassA_Zregion1''Xbob_YclassA_Zregion1' )並返回其簡化比率(在本例中為1.00000099009999 ),因此我可以快速檢查它們在結果方面的“差異”,不是根據它們的書寫方式。 例如, 2*aa*2對於我的目標是相同的。

我怎樣才能做到這一點?

注意事項

  1. 為了簡單起見,示例中的表達式是硬編碼的。 但在我的實際情況中,它們來自許多其他表達式和操作的序列。
  2. 並非所有類別的所有選項組合都會存在。 例如, Xcharles_YclassA_Zregion2可能不存在。 實際上,如果我要為現有的表達式名稱編寫一個表,它會被稀疏地填充。
  3. 我想使用dict重寫我的代碼來存儲表可能會解決我的問題。 但是我必須為此修改很多代碼。
  4. 除了我的目標的實際方面,我不知道Symbol (這是一個特定的類)和expression之間是否有任何形式上的區別。 從我閱讀的資料(例如, 這個)我沒有得出結論。 這種理解可能有助於解決問題。

TL;DR - 我試過的

我的目標是類似

def verify_ratio(vstr1, vstr2):
    """Compare the result of two different computations of the same quantity"""
    ratio = sp.N(sp.parsing.sympy_parser.parse_expr(vstr1)) / sp.parsing.sympy_parser.parse_expr(vstr2)
    print(vstr1 + ' / ' + vstr2, '=', sp.N(ratio))
    return

這沒有用。 下面的代碼說明了原因

import sympy as sp
a, b = sp.symbols('a,b', real=True, positive=True)
expr2 = 1.01 * a**1.01 * b**0.99
print(type(expr2), '->', expr2)
    
expr2b = sp.parsing.sympy_parser.parse_expr('expr2')
print(type(expr2b), '->', expr2b)

expr2c = sp.N(sp.parsing.sympy_parser.parse_expr('expr2'))
print(type(expr2c), '->', expr2c)
#print(sp.N(sp.parsing.sympy_parser.parse_expr('expr2')))

expr2d = sp.sympify('expr2')
print(type(expr2d), '->', expr2d)

output

<class 'sympy.core.mul.Mul'> -> 1.01*a**1.01*b**0.99
<class 'sympy.core.symbol.Symbol'> -> expr2
<class 'sympy.core.symbol.Symbol'> -> expr2
<class 'sympy.core.symbol.Symbol'> -> expr2

我需要一些接受字符串'expr2'並返回表達式1.01 * a**1.01 * b**0.99的東西。


我的嘗試都沒有達到目標。 沒有幫助的問題或鏈接(至少對我而言):

  1. 從字符串到 sympy 表達式
  2. https://docs.sympy.org/latest/tutorials/intro-tutorial/basic_operations.html
  3. https://docs.sympy.org/latest/modules/parsing.html
  4. https://docs.sympy.org/latest/modules/core.html#sympy.core.sympify.sympify
  5. https://docs.sympy.org/latest/tutorials/intro-tutorial/manipulation.html

如果在解析時要使用已映射到變量的表達式,則必須傳遞 python 用來跟蹤這些映射的字典,即locals()

>>> from sympy.abc import x
>>> from sympy import sympify, parse_expr
>>> y = x + 2
>>> sympify('y')
y
>>> sympify('y', locals=locals())
x + 2
>>> parse_expr('y', local_dict=locals())
x + 2

正如 Sympy Google 小組的 Oscar Benjamin 所建議的那樣, eval完成了這項工作

def verify_ratio(vstr1, vstr2):
    """Compare the result of two different computations of the same quantity"""
    print(vstr1 + ' / ' + vstr2, '=', eval(vstr1 + ' / ' + vstr2))
    return

表明這行得通的是

>>> import sys
>>> import sympy as sp
>>> a, b = sp.symbols('a,b', real=True, positive=True)
>>> a is eval('a')
True

就我而言,我在vstr1vstr2中使用的所有表達式和符號都是全局的。 如果嵌套在其他函數中,我可能需要將更多參數傳遞給verify_ratio ,就像 smichr 的解決方案一樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM