跳至主要内容

SymPy:Python 符号数学完整指南

学习如何通过精确的符号计算(而非数值近似)来执行代数、微积分、方程求解,甚至代码生成。
· 10分钟 阅读

使用 AI 探索

如果您希望用 Python 像数学家一样执行并表达代数运算,SymPy 就是答案。

SymPy 是 Symbolic Python(符号 Python)的缩写,它是一个用于执行符号计算的库。这意味着它可以像您在纸上演算那样,对方程进行展开、化简、求导和求解。 一个重要的扩展在于,含有未求值变量的数学表达式会保持符号形式。例如,8 的平方根会表示为 2*sqrt(2),而不是近似为 2.828。  

SymPy 的几个主要优势在于它是开源的、完全用 Python 编写,并且与其他 Python 库兼容。 

Sympy 的主要优势

Sympy 的主要优势。来源:Napkin AI 制图

SymPy 简史

SymPy 始于一个简单的想法:让符号计算人人可用。

它由内华达大学的学生 Ondřej Čertík 于 2006 年发起。他希望用纯 Python 打造一个轻量、灵活的符号数学库,让人们无需面对 Maple 或 Mathematica 等大型计算机代数系统的复杂性。 

2007 至 2010 年间,SymPy 在参与 Google Summer of Code 的过程中快速发展,化简、求解、微积分等核心模块得到了显著扩展。 

到 2012 年左右,SymPy 已经成熟到被集成进 SageMath,这标志着它被更广泛的科学 Python 生态认可为可靠的符号后端。时至今日,SymPy 的应用已超越代数,扩展至物理、几何、组合学、代码生成以及面向性能的编译工具等高级领域。

SymPy 入门

在探索 SymPy 的魔力之前,让我们先正确完成安装。

安装与设置

安装 SymPy 最简单、也最推荐的方法是使用 pip:

pip install sympy

如果您使用 Conda,命令如下:

conda install sympy

或者,您也可以直接从源码安装(对贡献者很有用):

git clone https://github.com/sympy/sympy.git

关于依赖:SymPy 完全运行在 Python 中,不依赖外部库。您可以安装 mpmath 等可选包以进行任意精度运算:

pip install mpmath

验证安装

要确认安装是否成功,打开 Python 并输入:

import sympy
print(sympy.__version__)
1.14.0

输出显示已安装的软件包版本。您现在可以用一个简单表达式测试该包:

from sympy import symbols

# Define x as a symbolic variable
x = symbols('x')

print((x + 2)**2)
(x + 2)**2

关于故障排查:

  • 如果看到 ModuleNotFoundError,请重新运行 pip install sympy。

  • 如遇版本冲突,升级 pip:pip install --upgrade pip

此外,还值得了解的是:如果您认为发现了 Bug 或希望请求新特性,也可以在 issue 区提交工单。关于安装方法的详细说明,请查阅官方文档。

基础用法

SymPy 提供了一个可交互的环境,您可以在其中以符号方式操作代数表达式。

from sympy import symbols, expand

#define x and y as symbolic variables
x, y = symbols('x y')

# create an algebraic expression
expr = (x + y)**2

expanded = expand(expr)
print(expanded)
x**2 + 2*x*y + y**2

上面的打印输出 x**2 + 2*x*y + y**2 是完全展开的形式,展示了 SymPy 如何执行精确的符号代数而非数值计算。

核心特性与功能

核心功能围绕符号计算构建——也就是将函数、方程和表达式作为符号而非数值来处理。

算术运算

您可以像对待代数变量一样对待符号变量。此外,函数可以在不同形式之间转换,如下代码所示。 

通过使用用于分配律的 expand() 和用于逆向化简的 factor(),SymPy 可以在代数表达式的展开式与因式分解式之间转换。

from sympy import symbols, expand, factor

# Define symbolic variables x and y
x, y = symbols('x y')

# Create an algebraic expression
expr = (x + y)**2

# Expand the expression to its full polynomial form
print(expand(expr))  

# Factor the expanded polynomial back into its compact form
print(factor(x**2 + 2*x*y + y**2)) 
x**2 + 2*x*y + y**2
(x + y)**2

化简技巧

化简是符号计算的核心。Sympy 中有一个通用函数 simplify(),可轻松化简有理式、三角式或代数表达式。

from sympy import simplify, trigsimp, sin, cos

# Create a trigonometric expression
expr = sin(x)**2 + cos(x)**2

# General simplification — recognizes that sin²x + cos²x = 1
print(simplify(expr)) 

# Trigonometric-specific simplification — also simplifies to 1
print(trigsimp(expr)) 

上述 simplify() 与 trigsimp() 的输出均为 1。 

微积分运算

SymPy 在微积分方面表现出色,因为它可以像手工解题那样,以符号方式进行求导、积分、极限,甚至级数展开,并且精确无误。

求导

求导请使用 diff() 函数。

from sympy import diff

# Define a symbolic polynomial expression
f = x**3 + 2*x**2 + x

# Compute the derivative of the expression with respect to x
df = diff(f, x)
print(df)
3*x**2 + 4*x + 1

积分

下面的代码计算符号表达式 f 关于变量 x 的不定积分,使用的是 SymPy 的 integrate() 函数。随后会打印得到的原函数。

from sympy import integrate

# Compute the indefinite integral of the expression f with respect to x
integral = integrate(f, x)
print(integral)
x**4/4 + 2*x**3/3 + x**2/2

极限

极限计算是经典的微积分操作,可以使用 SymPy 的 limit() 函数完成。其语法为:limit(f(x), x, x0)。例如,下面的代码计算当 x 趋近于 0 时表达式 sin(x)/x 的极限,并打印精确结果 one(1)。 

from sympy import limit, sin

# Compute the limit of sin(x)/x as x approaches 0 
limit_expr = limit(sin(x)/x, x, 0)
print(limit_expr) 

级数展开

series() 函数可用于在指定点附近计算数学表达式的泰勒或幂级数展开。

from sympy import series, exp

# Generate the Taylor series expansion of e^x around 0 up to 5 terms
print(series(exp(x), x, 0, 5))
1 + x + x**2/2 + x**3/6 + x**4/24 + O(x**5)

求和

SymPy 中的 summation() 函数可在某个区间上执行精确的符号求和,就像数学中的西格玛记号一样。

from sympy import summation, symbols

# Compute the symbolic sum of 1/n^2 from n = 1 to 5
n = symbols('n')
print(summation(1/n**2, (n, 1, 5)))  
5269/3600

方程求解

SymPy 让符号方程的求解变得简单——不仅是基础代数方程,还包括方程组、微分方程,甚至只允许整数解的丢番图方程。 

它具备强大的求解器,例如:

  • solve() 用于代数方程; 

  • linsolve() 用于线性方程组;以及 

  • dsolve() 用于微分方程,并在可能时给出精确解。 

代数方程

from sympy import Eq, solve
# Define and solve the equation x^2 - 4 = 0 symbolically
eq = Eq(x**2 - 4, 0)

print(solve(eq, x)) 
[-2, 2]

方程组

from sympy import linsolve, symbols

# Solve a system of linear equations:
# x + y = 5  and  x - y = 1
x, y = symbols('x y')
sol = linsolve([x + y - 5, x - y - 1], (x, y))

print(sol) # Outputs the solution as a set (x, y)
{(3, 2)}

微分方程

from sympy import Function, dsolve

# Define y as a symbolic function of x
y = Function('y')

# Define a second-order differential equation
diff_eq = Eq(y(x).diff(x, 2) - y(x), 0)

# Solve the differential equation symbolically
print(dsolve(diff_eq))
Eq(y(x), C1*exp(-x) + C2*exp(x))

矩阵运算

SymPy 在线性代数方面也很出色,因为它支持符号矩阵。您可以轻松处理矩阵,并执行加法、乘法等数学运算,就像常规代数一样。 

from sympy import Matrix

# Define symbolic matrices A and B
A = Matrix([[1, 2], [x, 3]])
B = Matrix([[x], [4]])

# Perform matrix multiplication
print(A * B)
Matrix([[x + 8], [x**2 + 12]])

高级运算

SymPy 还能以符号方式计算矩阵的重要性质,如行列式、逆矩阵、特征值与特征向量,并给出精确答案。 

# Compute the determinant of matrix A
A.det()      

# Compute the inverse of matrix A
A.inv()      

# Compute the eigenvalues of matrix A
A.eigenvals() 
{2 - sqrt(2*x + 1): 1, sqrt(2*x + 1) + 2: 1}

绘图功能

SymPy 不仅限于符号计算——它也支持数学表达式的可视化。借助内置绘图工具,您只需几行代码即可生成符号函数的 2D 甚至 3D 图。 

例如,下面的代码会生成一个 2D 图:  

from sympy.plotting import plot


# Plot the function x^2 over the range -5 to 5
plot(x**2, (x, -5, 5))

使用 SymPy 生成的 2D 图。

使用 SymPy 生成的 2D 图。

要生成 3D 图,可以使用如下所示的 plot3d() 函数。

from sympy.plotting import plot3d
from sympy import sin

# Generate a 3D surface plot of the function sin(x*y) over the specified x and y ranges
plot3d(sin(x*y), (x, -5, 5), (y, -5, 5))

SymPy 的 3D 绘图能力

SymPy 的 3D 绘图能力

如果您需要更多控制或样式,SymPy 也能与 Matplotlib 集成,以实现完全可定制的可视化。要了解更高级的可视化,请阅读我们的 Plotly Shapes 教程。

高级能力

SymPy 远不止基础代数——它扩展到了多项式、组合学,甚至物理学。

多项式操作

您可以轻松地定义和操作多项式。下面的代码从表达式创建一个多项式对象;然后通过 SymPy 的 Poly() 函数打印其次数和因式分解形式及系数。 

from sympy import Poly

# Create a symbolic polynomial in variable x
p = Poly(x**3 - 3*x**2 + x - 3, x)

# Print the degree of the polynomial (highest power of x)
print(p.degree())  

# Print the factorized form of the polynomial along with coefficients
print(p.factor_list())  
3
(1, [(Poly(x - 3, x, domain='ZZ'), 1), (Poly(x**2 + 1, x, domain='ZZ'), 1)])

对于复杂的多项式系统,SymPy 支持 Gröbner 基,它将一组多项式方程转化为更简洁规范的形式,便于求解。 

例如,下面的代码为多项式系统 [x*y - 1, y - x] 计算 Gröbner 基,也就是将方程重写为更简单、更有结构的形式,便于求解。输出表明该系统等价于更简洁的方程 x = y 与 y² = 1,现在可以直接求解。

from sympy import groebner, symbols

# Define x and y as symbolic variables
x, y = symbols('x y')

# Compute the Gröbner basis for the system of polynomial equations
print(groebner([x*y - 1, y - x], x, y))
GroebnerBasis([x - y, y**2 - 1], x, y, domain='ZZ', order='lex')

组合数学、离散数学与数论

SymPy 具备多种工具,可处理组合与数论问题。 

例如,在下面的代码中:

  • binomial(5, 2) 计算从 5 个元素中选 2 个的方式数(组合问题); 

  • factorial(6) 计算 6!,这是排列中常见的运算。 

  • isprime(19) 检查 19 是否为质数;以及 

  • factorint(100) 返回其精确素因子分解 {2: 2, 5: 2}。 

from sympy import binomial, factorial, isprime, factorint
print(binomial(5, 2))   # 10
print(factorial(6))     # 720
print(isprime(19))      # True
print(factorint(100))   # {2: 2, 5: 2}
10
720
True
{2: 2, 5: 2}
10
720
True
{2: 2, 5: 2}

这些函数共同展示了 SymPy 如何轻松且准确地处理离散数学。您还可以直接处理分拆、排列与组合。

几何与物理应用

SymPy 不仅适用于代数与微积分;它还提供了面向几何与物理的专门模块。 

在几何模块中,您可以定义点、直线、圆与多边形等数学对象。借助符号,您还可以得到直线的方程、交点、距离与中点。 

例如,要创建两个点并作一条通过它们的直线,只需这样:

from sympy import Point, Line, Circle

# Define two points and create a line passing through them
A, B = Point(0, 0), Point(1, 1)
L = Line(A, B)

# Print the symbolic equation of the line
print(L.equation())  
-x + y

除了几何功能,SymPy 还提供了非常实用的物理模块。借助该模块,您可以建模经典力学、量子系统、单位与量纲。无论是用米每秒计算速度,还是用符号求解运动方程,均可胜任。 

from sympy.physics.units import meter, second

# Define a symbolic physical quantity: velocity = 10 meters per second
velocity = 10 * meter / second
print(velocity)
10*meter/second

打印与 LaTeX 输出

SymPy 允许以多种格式打印符号表达式,包括:

  • 友好的美化打印
  • 基于 Unicode 的输出;以及 
  • LaTeX,它是科研论文和科学文档中的标准排版语言。 

您可以使用 pprint() 等函数,让您的方程在 Jupyter 笔记本或报告中看起来整洁专业。甚至可以用 latex() 将其直接用于论文写作,省去自行排版的麻烦。

from sympy import pprint, latex, symbols

# Define x and y as symbolic variables
x, y = symbols('x y')

# Now you can perform symbolic math operations
expr = (x+y)**3

# Pretty print to the console
pprint(expr)

# Print the LaTeX string
print(latex(expr))
     3
(x + y) 
\left(x + y\right)^{3}

代码生成与性能优化

虽然 SymPy 擅长符号计算,但它也允许您将符号表达式转换为优化后的可执行代码,用于高性能数值计算。

下面的代码使用 SymPy 的 codegen() 工具从符号表达式自动生成 C 语言代码,可直接用于嵌入式应用。

from sympy.utilities.codegen import codegen

# Generate C code for the symbolic function and save it as 'output'
codegen(("f", x**2 + 1), "C", "output")
[('output.c',
  '/******************************************************************************\n *                      Code generated with SymPy 1.14.0                      *\n *                                                                            *\n *              See http://www.sympy.org/ for more information.               *\n *                                                                            *\n *                       This file is part of \'project\'                       *\n ******************************************************************************/\n#include "output.h"\n#include <math.h>\n\ndouble f(double x) {\n\n   double f_result;\n   f_result = pow(x, 2) + 1;\n   return f_result;\n\n}\n'),
 ('output.h',
  "/******************************************************************************\n *                      Code generated with SymPy 1.14.0                      *\n *                                                                            *\n *              See http://www.sympy.org/ for more information.               *\n *                                                                            *\n *                       This file is part of 'project'                       *\n ******************************************************************************/\n\n\n#ifndef PROJECT__OUTPUT__H\n#define PROJECT__OUTPUT__H\n\ndouble f(double x);\n\n#endif\n\n")]

Lambdify

lambdify() 函数可将符号表达式转换为快速的数值 Python 函数。例如,下面的代码使用 lambdify 将对象 f 中存储的符号表达式转换为兼容 NumPy 的快速 Python 函数。对数组 [1, 2, 3] 进行求值时,它返回 [4, 9, 16]。 

from sympy import lambdify
import numpy as np

# Convert the symbolic expression into a fast numerical function using NumPy
f = lambdify(x, x**2 + 2*x + 1, 'numpy')

# Evaluate the function on a NumPy array
print(f(np.array([1, 2, 3])))
[ 4  9 16]

性能考量

由于 SymPy 追求符号精确性,因此可能比数值计算更慢。话虽如此,在处理大型或复杂表达式时,有多种方法可提升性能。 

例如,您可以使用 lambdify() 将符号表达式转换为与 NumPy 高效配合的快速数值函数,或在求值前先进行化简。 

您还可以通过公共子表达式消除、自动代码编译,以及与 Numba 或 Cython 等外部工具集成等技术,进一步加速密集型计算。

Python 生态中的 SymPy

SymPy 并非孤立运行——它能很好地与数据科学、教育与研究中的其他常用工具集成,并与更广泛的科学 Python 生态无缝衔接。

与其他库的集成

您可以将 SymPy 与以下库结合使用:

  • NumPy/SciPy ——高性能数值计算
  • Matplotlib ——可视化
  • Pandas ——符号化数据分析
import numpy as np
from sympy import lambdify

# Convert the symbolic expression x^2 into a fast NumPy-compatible function
f = lambdify(x, x**2, 'numpy')

# Evaluate the function on a NumPy array from 0 to 4
print(f(np.arange(5)))
[ 0  1  4  9 16]

教育应用

SymPy 广泛用于课堂与自学环境,因为它与纸笔推导的教学方式一致——按步骤,以符号形式进行。在 Jupyter 笔记本中,学生可以对代数、微积分或物理方程进行实时实验,并看到精确的符号结果,而非粗略近似。参见Jupyter Notebook 速查表以开始使用。

相关项目与集成

SymPy 还与其他强大的数学工具紧密相连,例如:

  • SageMath ——一个大型数学系统,使用 SymPy 作为后端。
  • SymEngine ——SymPy 内核的更快 C++ 复刻实现。
  • Pyomo ——集成优化建模(参见使用 Pyomo 进行优化)。

社区、贡献与开发

SymPy 的繁荣源于强大的开源社区。全球的开发者、研究者、教师与学生共同参与,使 SymPy 日益完善与健壮。任何人都可以在无需许可或企业会员身份的情况下提供帮助、提问或参与。

贡献与开发

有意贡献的人通常会 fork 仓库、进行修改、使用 pytest 运行测试套件,然后提交 Pull Request 以供评审。

为确保每次更改都可靠,项目采用代码审查流程。项目还提供测试框架,贡献者可在提交前在本地机器上运行测试。 

报告问题与寻求支持

关于 Bug 或求助:

  • 在 GitHub 的 SymPy Issues 下提交问题
  • 在 Stack Overflow 提问 
  • 加入 SymPy 的 Gitter 或邮件列表

您对问题描述得越清晰(包括代码、预期结果、实际结果以及所用 SymPy 版本),社区就能越快提供帮助。 

未来方向

SymPy 仍在不断发展,正在扩展功能、提升性能,并与 AI 工具集成。同时也在改进代码生成、文档与教育用途。我们尤其欢迎新贡献者帮助梳理 Bug 与问题、完善文档,并为符号数学添加新特性。

结论

SymPy 是一个强大的库,能让您在 Python 中进行符号数学。这使它在教育、研究,乃至实际工程中都大有用武之地。它提供了一个开源生态,您可以在其中执行各类数学与代数运算与变换。SymPy 值得学生、开发者与研究人员了解与使用。动手试试吧——打开 Jupyter 笔记本,导入 sympy,开始探索。 

您还可以参考以下资料以继续阅读:

Vikash Singh

作者

Vikash Singh

在数据科学、人工智能、分析与数据战略方面经验丰富的专业人士。

常见问题

SymPy 与 Mathematica 或 Maple 等其他计算机代数系统的主要区别是什么?

SymPy 是开源且完全用 Python 编写,更易集成进 Python 工作流。Mathematica 和 Maple 为商业软件,速度更快、功能更多,但 SymPy 对大多数学术与开发场景已足够强大。

SymPy 相比数值计算,如何处理符号表达式?

SymPy 默认以符号方式处理表达式——它保留变量为符号,并返回精确的代数结果,而非近似的数值。当需要时,您可以使用 evalf() 或通过 subs() 代入数值来切换到数值计算。

SymPy 能用于实时数据处理吗,还是更适合离线计算?

SymPy 并不适合实时或高频数据处理。它更适用于离线分析、推导与校验公式,以及进行符号操作。

SymPy 有哪些可能不那么为人所知的高级功能?

一些不太为人知的功能包括:生成 C/Fortran 代码、支持量子物理以及用于多项式系统的 Gröbner 基。

SymPy 的性能与其他 Python 科学计算库相比如何?

SymPy 比 NumPy 或 SciPy 等数值库更慢,因为它更注重符号精确性而非速度。但可通过 lambdify()、autowrap() 或使用 SymEngine 作为后端来提升性能。

主题