去掉前因子,不改变其余的表达式

  • 本文关键字:改变 表达式 python sympy
  • 更新时间 :
  • 英文 :


我在sympy中有这个表达式

expr = 60378125*139**(13/16)*2143750**(1/8)*x**(9/4)*m**(1/4)/(15420489728*y**(1/4)*z**(3/4))

(注意:这实际上来自其他计算,太长了,不能在这里发布。所以我不确定我是否可以使用任何不同的东西,例如,使用Rational的替代表达式。

我想去掉所有的数字因子,保留表达式的其余部分,如

expr2 = x**(9/4)*m**(1/4)/(y**(1/4)*z**(3/4))

我怎样才能轻松地做到这一点?

其他答案也很好,但这里有更简单的方法:

In [5]: from sympy import symbols, Mul, Rational as R
In [6]: x, y, z, m = symbols('x y z m')
In [7]: expr = (60378125 * 139**R(13,16) * 2143750**R(1,8)
...:         * x**R(9,4) * m**R(1,4) / (15420489728 * y**R(1,4) * z**R(3,4)))
In [8]: expr
Out[8]: 
13                       
──                       
16 8 _________ 4 ___  9/4
60378125⋅139  ⋅╲╱ 2143750 ⋅╲╱ m ⋅x   
─────────────────────────────────────
4 ___  3/4       
15420489728⋅╲╱ y ⋅z          
In [9]: Mul.make_args(expr)
Out[9]: 
⎛                13                                       ⎞
⎜                ──                                       ⎟
⎜  60378125      16  8 _________  4 ___   9/4    1     1  ⎟
⎜───────────, 139  , ╲╱ 2143750 , ╲╱ m , x   , ─────, ────⎟
⎜15420489728                                   4 ___   3/4⎟
⎝                                              ╲╱ y   z   ⎠
In [10]: [f for f in Mul.make_args(expr) if not f.is_number]
Out[10]: 
⎡4 ___   9/4    1     1  ⎤
⎢╲╱ m , x   , ─────, ────⎥
⎢             4 ___   3/4⎥
⎣             ╲╱ y   z   ⎦
In [11]: Mul(*[f for f in Mul.make_args(expr) if not f.is_number])
Out[11]: 
4 ___  9/4
╲╱ m ⋅x   
──────────
4 ___  3/4
╲╱ y ⋅z  

这种使用make_args来获取因子并对其进行过滤的方法可以用于更一般的谓词,因此您可以使用它来选择基于某些任意条件的Mul因子的任何子集。

实际上你要做的是一个非常常见的操作,所以有一个特定的方法来完成它:

In [19]: expr.as_independent(x, y, z, m, as_Add=False)
Out[19]: 
⎛            13                        ⎞
⎜            ──                        ⎟
⎜            16 8 _________  4 ___  9/4⎟
⎜60378125⋅139  ⋅╲╱ 2143750   ╲╱ m ⋅x   ⎟
⎜──────────────────────────, ──────────⎟
⎜       15420489728          4 ___  3/4⎟
⎝                            ╲╱ y ⋅z   ⎠
In [20]: expr.as_independent(x, y, z, m, as_Add=False)[1]
Out[20]: 
4 ___  9/4
╲╱ m ⋅x   
──────────
4 ___  3/4
╲╱ y ⋅z   
In [21]: expr.as_independent(*expr.free_symbols, as_Add=False)[1]
Out[21]: 
4 ___  9/4
╲╱ m ⋅x   
──────────
4 ___  3/4
╲╱ y ⋅z

你可以使用模式匹配:

from sympy import *
var("x, m, y, z")
expr1 = 60378125*139**(13/16)*2143750**(1/8)*x**(9/4)*m**(1/4)/(15420489728*y**(1/4)*z**(3/4))
# converts float numbers to rational numbers
expr1 = nsimplify(expr1)
# pattern matching:
# w1 selects every number
# w2 selects everything that is not a number
w1 = Wild("w1", properties=[lambda t: t.is_Number])
w2 = Wild("w2", exceptions=[lambda t: t.is_Number])
# find a product given by a number and something else
matches = expr1.match(w1 * w2)
# the final expression is just everything else without the factor (number)
expr = matches[w2]
print(expr)
# out: m**(1/4)*x**(9/4)/(y**(1/4)*z**(3/4))

您可以使用Rational()定义表达式来处理作为有理数的指数,然后创建一个列表来存储非数字因子。接下来,遍历表达式的因子,并使用isinstance()检查因子是否为幂。如果是幂,则使用as_base_exp()将底数和指数分开。检查基数是否是符号而不是数字,如果基数是符号或因子是符号,则将其附加到non_numeric_factors。遍历所有因子后,将non_numeric_factors相乘,结果是一个只包含非数字因子的新表达式:

from sympy import symbols, Mul, Pow, Rational
x, y, z, m = symbols('x y z m')
expr = (60378125 * 139**(Rational(13, 16)) *
2143750**(Rational(1, 8)) * x**(Rational(9, 4)) *
m**(Rational(1, 4)) /
(15420489728 * y**(Rational(1, 4)) * z**(Rational(3, 4))))
non_numeric_factors = []
for factor in Mul.make_args(expr):
if isinstance(factor, Pow):
base, exp = factor.as_base_exp()
if base.is_symbol:
non_numeric_factors.append(factor)
elif factor.is_symbol:
non_numeric_factors.append(factor)
expr2 = Mul(*non_numeric_factors)
print(expr2)

生产

m**(1/4)*x**(9/4)/(y**(1/4)*z**(3/4))

编辑:支持任何输入字符串,只要parse_exp()你收到作为你的输入,而不是处理硬编码的一个:

from sympy import symbols, Mul, Pow, nsimplify, parse_expr
x, y, z, m = symbols('x y z m')
# Replace this with the input string you receive
input_str = '60378125*139**(13/16)*2143750**(1/8)*x**(9/4)*m**(1/4)/(15420489728*y**(1/4)*z**(3/4))'
# Parse the string into a Sympy expression
expr = parse_expr(input_str, evaluate=False)
# Simplify the expression, which will convert floating-point numbers to fractions
expr = nsimplify(expr)
non_numeric_factors = []
for factor in Mul.make_args(expr):
if isinstance(factor, Pow):
base, exp = factor.as_base_exp()
if base.is_symbol:
non_numeric_factors.append(factor)
elif factor.is_symbol:
non_numeric_factors.append(factor)
expr2 = Mul(*non_numeric_factors)
print(expr2)

最新更新