在 Sympy 中收集类似的表达式
Collecting like term of an expression in Sympy
我目前正在处理多个变量的函数,需要收集类似的项以尝试简化表达式。
假设表达式写成如下:
x = sympy.Symbol('x')
y = sympy.Symbol('y')
k = sympy.Symbol('k')
a = sympy.Symbol('a')
z = k*(y**2*(a + x) + (a + x)**3/3) - k((2*k*y*(a + x)*(n - 1)*(-k*(y**2*(-a + x) + (-a + x)**3/3) + k*(y**2*(a + x) + (a + x)**3/3)) + y)**2*(-a + k*(n - 1)*(y**2 + (a + x)**2)*(-k*(y**2*(-a + x)))))
zEx = z.expand()
print type(z)
print type(zEx)
编辑:格式化以增加清晰度并更改表达式 z 以使问题更容易理解。
说 z
包含如此多的术语,需要用眼睛筛选它们。并选择适当的术语,将花费不尽人意的时间。
我想收集所有只有 a**1 的倍数的项。我不关心 a 的二次方或更高次方,也不关心不包含 a 的项。
z
和zEx
return的类型如下:
print type(z)
print type(zEx)
>>>
<class 'sympy.core.add.Add'>
<class 'sympy.core.mul.Mul'>
有谁知道我如何收集 a
的倍数而不是 a^0 或 a^2 的项?
tl'dr
where z(x,y) with constants a and k described by z
and zEx
and their type(): How can remove all non-a
terms from z
并从表达式中删除 a
的所有二次项或更高项?这样剩下的就是 仅 包含 a
.
单位幂的项
到头来只是一行。 @asmeurer 让我走上了正确的轨道(查看 post 下面的评论)。这是代码;解释如下:
from sympy import *
from sympy.parsing.sympy_parser import parse_expr
import sys
x, y, k, a = symbols('x y k a')
# modified string: I added a few terms
z = x*(k*a**9) + (k**1)*x**2 - k*a**8 + y*x*(k**2) + y*(x**2)*k**3 + x*(k*a**1) - k*a**3 + y*a**5
zmod = Add(*[argi for argi in z.args if argi.has(a)])
那么zmod
就是
a**9*k*x - a**8*k + a**5*y - a**3*k + a*k*x
所以让我们更仔细地看一下:
z.args
只是表达式中所有单独术语的集合(请注意,符号也被解析,这使事情变得更容易):
(k*x**2, a**5*y, -a**3*k, -a**8*k, a*k*x, a**9*k*x, k**2*x*y, k**3*x**2*y)
在列表理解中,您然后 select 使用函数 has
包含 a
的所有术语。然后可以使用 Add
将所有这些术语粘合在一起,从而为您提供所需的输出。
编辑
以上returns所有包含一个a
的表达式。如果只想以单位幂过滤掉包含a
的表达式,可以使用collect
和Mul
:
from sympy import *
from sympy.parsing.sympy_parser import parse_expr
import sys
x, y, k, a = symbols('x y k a')
z2 = x**2*(k*a**1) + (k**1)*x**2 - k*a**8 + y*x*(k**2) + y*(x**2)*k**3 + x*k*a - k*a**3 + y*a**1
zc = collect(z2, a, evaluate=False)
zmod2 = Mul(zc[a], a)
那么zmod2
就是
a*(k*x**2 + k*x + y)
和zmod2.expand()
a*k*x**2 + a*k*x + a*y
这是正确的。
更新后z
你提供我运行:
z3 = k*(y**2*(a + x) + (a + x)**3/3) - k((2*k*y*(a + x)*(n - 1)*(-k*(y**2*(-a + x) + (-a + x)**3/3) + k*(y**2*(a + x) + (a + x)**3/3)) + y)**2*(-a + k*(n - 1)*(y**2 + (a + x)**2)*(-k*(y**2*(-a + x)))))
zc3 = collect(z3.expand(), a, evaluate=False)
zmod3 = Mul(zc3[a], a)
然后获取 zmod3.expand()
:
a*k*x**2 + a*k*y**2
这是您想要的结果吗?
PS:感谢@asmeurer 提供的所有这些有用的评论!
要遍历表达式的项,请使用 expr.args
。
我不清楚 a
应该是什么,但 collect
function 可能会满足您的要求。
除了给出的其他答案,您还可以使用collect
作为字典。
print(collect(zEx,a,evaluate=False)[a])
产生表达式
k*x**2 + k*y**2
我目前正在处理多个变量的函数,需要收集类似的项以尝试简化表达式。
假设表达式写成如下:
x = sympy.Symbol('x')
y = sympy.Symbol('y')
k = sympy.Symbol('k')
a = sympy.Symbol('a')
z = k*(y**2*(a + x) + (a + x)**3/3) - k((2*k*y*(a + x)*(n - 1)*(-k*(y**2*(-a + x) + (-a + x)**3/3) + k*(y**2*(a + x) + (a + x)**3/3)) + y)**2*(-a + k*(n - 1)*(y**2 + (a + x)**2)*(-k*(y**2*(-a + x)))))
zEx = z.expand()
print type(z)
print type(zEx)
编辑:格式化以增加清晰度并更改表达式 z 以使问题更容易理解。
说 z
包含如此多的术语,需要用眼睛筛选它们。并选择适当的术语,将花费不尽人意的时间。
我想收集所有只有 a**1 的倍数的项。我不关心 a 的二次方或更高次方,也不关心不包含 a 的项。
z
和zEx
return的类型如下:
print type(z)
print type(zEx)
>>>
<class 'sympy.core.add.Add'>
<class 'sympy.core.mul.Mul'>
有谁知道我如何收集 a
的倍数而不是 a^0 或 a^2 的项?
tl'dr
where z(x,y) with constants a and k described by z
and zEx
and their type(): How can remove all non-a
terms from z
并从表达式中删除 a
的所有二次项或更高项?这样剩下的就是 仅 包含 a
.
到头来只是一行。 @asmeurer 让我走上了正确的轨道(查看 post 下面的评论)。这是代码;解释如下:
from sympy import *
from sympy.parsing.sympy_parser import parse_expr
import sys
x, y, k, a = symbols('x y k a')
# modified string: I added a few terms
z = x*(k*a**9) + (k**1)*x**2 - k*a**8 + y*x*(k**2) + y*(x**2)*k**3 + x*(k*a**1) - k*a**3 + y*a**5
zmod = Add(*[argi for argi in z.args if argi.has(a)])
那么zmod
就是
a**9*k*x - a**8*k + a**5*y - a**3*k + a*k*x
所以让我们更仔细地看一下:
z.args
只是表达式中所有单独术语的集合(请注意,符号也被解析,这使事情变得更容易):
(k*x**2, a**5*y, -a**3*k, -a**8*k, a*k*x, a**9*k*x, k**2*x*y, k**3*x**2*y)
在列表理解中,您然后 select 使用函数 has
包含 a
的所有术语。然后可以使用 Add
将所有这些术语粘合在一起,从而为您提供所需的输出。
编辑
以上returns所有包含一个a
的表达式。如果只想以单位幂过滤掉包含a
的表达式,可以使用collect
和Mul
:
from sympy import *
from sympy.parsing.sympy_parser import parse_expr
import sys
x, y, k, a = symbols('x y k a')
z2 = x**2*(k*a**1) + (k**1)*x**2 - k*a**8 + y*x*(k**2) + y*(x**2)*k**3 + x*k*a - k*a**3 + y*a**1
zc = collect(z2, a, evaluate=False)
zmod2 = Mul(zc[a], a)
那么zmod2
就是
a*(k*x**2 + k*x + y)
和zmod2.expand()
a*k*x**2 + a*k*x + a*y
这是正确的。
更新后z
你提供我运行:
z3 = k*(y**2*(a + x) + (a + x)**3/3) - k((2*k*y*(a + x)*(n - 1)*(-k*(y**2*(-a + x) + (-a + x)**3/3) + k*(y**2*(a + x) + (a + x)**3/3)) + y)**2*(-a + k*(n - 1)*(y**2 + (a + x)**2)*(-k*(y**2*(-a + x)))))
zc3 = collect(z3.expand(), a, evaluate=False)
zmod3 = Mul(zc3[a], a)
然后获取 zmod3.expand()
:
a*k*x**2 + a*k*y**2
这是您想要的结果吗?
PS:感谢@asmeurer 提供的所有这些有用的评论!
要遍历表达式的项,请使用 expr.args
。
我不清楚 a
应该是什么,但 collect
function 可能会满足您的要求。
除了给出的其他答案,您还可以使用collect
作为字典。
print(collect(zEx,a,evaluate=False)[a])
产生表达式
k*x**2 + k*y**2