python学习笔记——sympy
SymPy 是 Python 的符号计算库,核心是用 “数学符号” 而非数值进行运算,支持推导公式、求导积分、解方程等。
基础元素
其基础元素分为四类:变量、数值、函数、表达式,所有高级操作都建立在这四类元素之上
一、变量(Symbol):符号计算的起点
变量是 SymPy 中最基础的元素,代表数学公式中的未知量。
创建方式(返回一个 Symbol 类实例,即符号变量对象):
import sympy
# 单个符号变量
x = sympy.Symbol("x")
# 批量创建多个变量(推荐写法)
a, b, c = sympy.symbols("a, b, c")
# 自定义名称的变量(支持任意字符串)
crazy = sympy.symbols('unrelated')
必填参数:
| 参数名 | 类型 | 说明 |
|---|---|---|
| name | str | 符号的显示名称,如 "x"、"t"、"alpha" |
可选参数:
| 参数 | 类型 | 默认 | 含义 |
|---|---|---|---|
| commutative | bool | True | 是否可交换(加法 / 乘法可交换) |
| real | bool | False | 是否为实数 |
| integer | bool | False | 是否为整数 |
| positive | bool | False | 是否正数 |
| negative | bool | False | 是否负数 |
| zero | bool | False | 是否等于 0 |
| finite | bool | True | 是否有限数 |
常见用法
x = sympy.Symbol("x", real=True)
print(x.name) # 'x'
print(x.is_real) # True
print(x.is_positive)# False
print(x.is_integer) # False
二、数值(精确数值):无误差的数学常数
SymPy 提供了高精度数值类型,避免 Python 原生浮点数的精度丢失问题。
1. 基础数值类型
# 整数(支持任意大小)
i = sympy.Integer(26)
print(i ** 50) # 完全精确的大整数运算,无溢出问题
# 浮点数(指定精度,注意字符串传参避免误差)
print(sympy.Float(0.3, 25)) # 直接传float会保留浮点误差:0.2999999999999999888977698
print(sympy.Float('0.3', 25)) # 传字符串得到精确值:0.3000000000000000000000000
# 有理数(分数形式,无误差)
r = sympy.Rational(11, 13)
print(r) # 11/13
| 类型 | 构造函数 | 传入参数 | 存储形式 | 精度特点 | 适用场景 |
|---|---|---|---|---|---|
| 整数 | sympy.Integer() | 整数 / 数字字符串 | 整数 | 完全精确,支持超大数 | 整数运算、离散数学、计数 |
| 浮点数 | sympy.Float() | 数值 / 字符串 + 有效位数 | 高精度小数 | 可自定义精度,传字符串才无误差 | 科学计算、需要指定小数位数 |
| 有理数 | sympy.Rational() | 分子、分母(两个整数) | 最简分数 | 全程无误差,自动约分 | 分数运算、代数推导、微积分 |
2. 内建数学常数
sympy.pi # π(符号级精确,不是近似值)
sympy.E # 自然对数的底e
sympy.oo # 无穷大∞
三、函数(Function):符号级运算的工具
SymPy 的函数分为内建函数和自定义函数两类,支持符号级的推导和运算。
1. 自定义函数
# 创建未定义的符号函数
f = sympy.Function("f")
print(f, type(f)) # 输出:f <class 'sympy.core.function.UndefinedFunction'>
自定义函数可作为未知函数参与表达式构建,如 f(x)、f(x+1)
一般专门用于:
微分方程
函数方程
符号推导
未知函数的求导 / 积分 / 极限
2. 内建函数(常用示例)
# 三角函数
g = sympy.sin
print(g, type(g)) # 输出:sin <class 'sympy.core.function.FunctionClass'>
# 符号级运算示例
print(sympy.sin(sympy.pi)) # 输出:0(精确值,不是近似值)
print(sympy.sin(1)) # 输出:sin(1)(保留符号形式,不直接计算数值)
其他常用内建函数:cos/tan/exp/log/sqrt/abs 等
| 函数名 | 数学含义 | 代码示例 | 输出结果 |
|---|---|---|---|
| sympy.sin(x) | 正弦函数 | sin(pi) | 0 |
| sympy.cos(x) | 余弦函数 | cos(pi) | -1 |
| sympy.tan(x) | 正切函数 | tan(pi/4) | 1 |
| sympy.exp(x) | 自然指数 eˣ | exp(0) | 1 |
| sympy.log(x) | 自然对数 ln (x) | log(E) | 1 |
| sympy.log(x, base) | 以 base 为底的对数 | log(8,2) | 3 |
| sympy.sqrt(x) | 平方根 √x | sqrt(4) | 2 |
| sympy.abs(x) | 绝对值 | abs(-5) | 5 |
| sympy.factorial(x) | 阶乘 x! | factorial(5) | 120 |
| sympy.floor(x) | 向下取整 | floor(3.9) | 3 |
| sympy.ceiling(x) | 向上取整 | ceiling(3.1) | 4 |
| sympy.sign(x) | 符号函数 | sign(-10) | -1 |
| 函数名 | 作用 | 代码示例 |
|---|---|---|
| diff(expr, x) | 对 x 求导 | diff(x**2, x) → 2*x |
| integrate(expr, x) | 不定积分 | integrate(2*x, x) → x² |
| integrate(expr, (x,a,b)) | 定积分 | integrate(x, (x,0,1)) → 1/2 |
| limit(expr, x, c) | 求极限 | limit(sin(x)/x, x, 0) → 1 |
| series(expr, x, 0, n) | 泰勒展开 | series(sin(x), x, 0, 5) |
| simplify(expr) | 自动化简 | simplify((x**2-1)/(x-1)) → x+1 |
| factor(expr) | 因式分解 | factor(x**2-1) → (x-1)(x+1) |
| expand(expr) | 展开表达式 | expand((x+1)**2) → x²+2x+1 |
四、表达式(Expression):数学公式的符号级描述
表达式是 SymPy 的核心,由变量、数值、函数组合而成,是对计算过程的符号级描述。
1. 两种创建方式
# 方式1:直接通过变量运算构建
expr = 1 + 2 * x**2 + 3 * x**3
print(expr) # 输出:3*x**3 + 2*x**2 + 1
# 方式2:通过 sympify 从字符串解析(快速创建复杂公式)
expr2 = sympy.sympify("2*x**2 + 3*x**3 + 1")
expr3 = sympy.sympify("exp(t)/(1 + exp(2 * t))")
print(expr3) # 输出:exp(t)/(exp(2*t) + 1)
2. 表达式的基础操作
# 代入数值计算
print(expr.subs(x, 2)) # 输出:33(3*2³ + 2*2² + 1 = 33)
#sub一次性多个带入:使用字典传参
e = x + y**2
e.subs({x: 2, y: 3}) # 2 + 9 = 11
#将符号表达式转为浮点数值,常和 subs 搭配使用
expr.evalf(n) # n 为保留有效数字,默认 15 位 #
# 函数调用示例
print(f(i)) # 输出:f(26)(自定义函数调用)
print(f(x)) # 输出:f(x)(符号变量调用)
| 操作 | 方法 | 核心用途 | 示例用法(2-3个) |
|---|---|---|---|
| 表达式创建 | 直接运算 / sympify() | 构建符号公式 | 1. 直接构建:expr = x**2 + 3*x + 22. 字符串转表达式:expr = sympy.sympify("sin(x) + x**2")3. 多元表达式:expr = x*y + 2*x - y**2 |
| 变量/数值代入 | subs() | 替换符号、代入数值 | 1. 单数值代入:(x**2+2*x).subs(x, 3)2. 符号替换:(x**2).subs(x, y+1)3. 多变量代入:(x+y).subs({x:2, y:5}) |
| 转浮点数 | evalf() | 输出小数结果 | 1. 默认精度:sympy.sqrt(2).evalf()2. 指定精度:sympy.pi.evalf(6)3. 代入后求值:sympy.sin(x).subs(x,1).evalf() |
| 通用化简 | simplify() | 一键化简表达式 | 1. 分式化简:sympy.simplify((x**2-1)/(x-1))2. 三角化简:sympy.simplify(sympy.sin(x)**2 + sympy.cos(x)**2)3. 多项式化简:sympy.simplify((x**3+x**2)/x) |
| 展开括号 | expand() | 多项式展开 | 1. 完全平方展开:sympy.expand((x+1)**2)2. 多项式乘积展开:sympy.expand((x+2)*(x-3))3. 多元展开:sympy.expand((x+y)**2) |
| 因式分解 | factor() | 多项式分解 | 1. 平方差分解:sympy.factor(x**2-9)2. 二次多项式分解:sympy.factor(x**2-5*x+6)3. 高次分解:sympy.factor(x**3-x) |
| 求导 | diff() | 一阶/高阶/偏导数 | 1. 一阶导数:sympy.diff(x**4, x)2. 高阶导数:sympy.diff(x**4, x, 2)3. 偏导数:sympy.diff(x**2*y, x) |
| 积分 | integrate() | 不定积分、定积分 | 1. 不定积分:sympy.integrate(3*x**2, x)2. 定积分:sympy.integrate(x, (x, 0, 2))3. 三角积分:sympy.integrate(sympy.sin(x), x) |
| 求极限 | limit() | 函数极限计算 | 1. 重要极限:sympy.limit(sympy.sin(x)/x, x, 0)2. 无穷极限:sympy.limit((x+1)/x, x, sympy.oo)3. 分式极限:sympy.limit((x**2-4)/(x-2), x, 2) |
| 解方程 | solve() | 代数方程、方程组 | 1. 一元一次方程:sympy.solve(3*x-6, x)2. 一元二次方程:sympy.solve(x**2-4, x)3. 二元方程组:sympy.solve([x+y-5, x-y-1],[x,y]) |
| 解微分方程 | dsolve() | 常微分方程 | f = sympy.Function("f")1. 一阶微分:sympy.dsolve(f(x).diff(x)-2*x, f(x))2. 二阶微分:sympy.dsolve(f(x).diff(x,2)+f(x), f(x))3. 指数微分:sympy.dsolve(f(x).diff(x)-f(x), f(x)) |
| 操作 | 方法 | 核心用途 | 示例用法(2-3个) |
| 通用全能化简 | simplify() | 综合所有化简规则,一键智能化简,适配所有表达式 | 1. 分式通用化简:sympy.simplify((x**2-1)/(x-1)) 2. 三角恒等化简:sympy.simplify(sympy.sin(x)**2 + sympy.cos(x)**2) 3. 混合表达式化简:sympy.simplify((x**3 + 2*x**2)/x) |
| 三角函数专项化简 | trigsimp() | 专门针对三角函数、反三角函数精准化简,比simplify更高效 | 1. 三角平方化简:sympy.trigsimp(sympy.sin(x)**2 + sympy.cos(x)**2) 2. 二倍角化简:sympy.trigsimp(2*sympy.sin(x)*sympy.cos(x)) 3. 复杂三角合并:sympy.trigsimp(sympy.cos(x)**2 - sympy.sin(x)**2) |
| 幂函数专项化简 | powsimp() | 专门化简幂次、指数、根式表达式,统一幂式格式 | 1. 同底数幂合并:sympy.powsimp(x**2 * x**3) 2. 幂的乘方化简:sympy.powsimp((x**2)**3) 3. 多元幂次化简:sympy.powsimp(x**4 * y**2 / x**2) |
| 组合数专项化简 | combsimp() | 专门化简排列数、组合数、阶乘相关离散数学表达式 | 1. 组合数化简:sympy.combsimp(sympy.binomial(x,2) + sympy.binomial(x,1)) 2. 阶乘分式化简:sympy.combsimp(sympy.factorial(x+1)/sympy.factorial(x)) 3. 叠加组合化简:sympy.combsimp(sympy.binomial(x,3) + sympy.binomial(x,2)) |
| 有理式专项化简 | ratsimp() | 专门化简多项式分式,通分、合并有理表达式,去除冗余项 | 1. 双分式合并:sympy.ratsimp(1/(x+1) + 1/(x-1)) 2. 复杂分式化简:sympy.ratsimp((x**2-4)/(x-2)) 3. 多项式分式整理:sympy.ratsimp((x**3+1)/(x+1)) |
使用sympy 对NumPy数组进行矢量化操作
expr_func = sympy.lambdify(x, expr, 'numpy')#返回值:一个普通 Python 函数
#意思:
#把符号 x 作为参数
#把 SymPy 表达式 expr 转成函数
#使用 numpy 后端(支持数组、广播)
#使用:
expr_func(np.array([1,2,3]))
expr_func(1.0)
使用范例:
import sympy as sp
import numpy as np
x = sp.Symbol('x')
expr = x / (x + x**2) # 符号表达式
# 转成 numpy 函数
expr_func = sp.lambdify(x, expr, 'numpy')
# 1. 单个数值
print(expr_func(1.0)) # 0.5
# 2. numpy 数组(矢量化,超快)
xs = np.array([1, 2, 3, 4], dtype=float)
print(expr_func(xs)) # [0.5 0.33333333 0.25 0.2 ]
sympy.solve 解方程
一、基础用法:单个方程求解
1. 直接求解(默认变量)
import sympy as sp
x = sp.Symbol('x')
# 求解一元二次方程 x² + 2x - 3 = 0
sol = sp.solve(x**2 + 2*x - 3)
print(sol) # 输出:[-3, 1]
特点:不指定求解变量时,默认对表达式中的唯一符号变量求解。
结果:返回解的列表,按从小到大排序。
2. 指定求解变量
# 求解三角方程 sin(x) - cos(x) = 0
sol = sp.solve(sp.sin(x) - sp.cos(x), x)
print(sol) # 输出:[-3*pi/4, pi/4]
特点:第二个参数显式指定求解变量,适合多变量表达式或需要明确求解对象的场景。
结果:返回符号形式的解(如 pi/4),而非数值近似。
二、带参数的符号方程求解
a, b, c = sp.symbols('a b c')
# 求解一元二次方程 ax² + bx + c = 0
sol = sp.solve(a*x**2 + b*x + c, x)
print(sol)
# 输出:[(-b + sqrt(-4*a*c + b**2))/(2*a), -(b + sqrt(-4*a*c + b**2))/(2*a)]
特点:方程含参数时,solve 会返回符号形式的通解(即一元二次方程求根公式)。
用途:推导通用公式、建立符号模型时非常实用。
三、方程组求解(线性 / 非线性)
1. 线性方程组
x, y = sp.symbols('x y')
eq1 = x + 2*y - 1
eq2 = x - y + 1
# 求解方程组,dict=True 以字典形式返回解
sol = sp.solve([eq1, eq2], [x, y], dict=True)
print(sol) # 输出:[{x: -1/3, y: 2/3}]
格式:方程列表 [eq1, eq2] + 变量列表 [x, y]。
dict=True:解以字典形式返回,便于后续代入表达式使用。
2. 非线性方程组(高次方程)
eq1 = x**2 - y
eq2 = y**2 - x
sol = sp.solve([eq1, eq2], [x, y], dict=True)
print(sol)
# 输出:[{x: 0, y: 0}, {x: 1, y: 1}, {x: (-1/2 - sqrt(3)*I/2)**2, y: -1/2 - sqrt(3)*I/2}, {x: (-1/2 + sqrt(3)*I/2)**2, y: -1/2 + sqrt(3)*I/2}]
特点:高次方程组可能返回多个解(含复数解),结果为解的字典列表。
说明:SymPy 会自动处理复数解,无需额外配置。
四、关键参数说明
| 参数 | 作用 | 示例 |
|---|---|---|
| expr | 待求解的表达式(默认 expr=0) | sp.solve(x**2 - 4) |
| symbols | 求解变量(可单个 / 多个) | sp.solve(x + y - 1, x) |
| dict=True | 以字典形式返回解,便于后续代入 | sp.solve([eq1, eq2], [x,y], dict=True) |
五、常见注意事项
符号定义优先:使用 solve 前必须用 symbols() 定义变量,否则会报错。
方程形式:表达式默认按 expr=0 求解,无需显式写 Eq(expr, 0)。
解的数量:高次方程 / 方程组可能返回多个解,需遍历结果或筛选实解。
复数解:默认包含复数解,若只需实解,可添加 dict=True 后过滤 x.is_real
sympy 矩阵相关
看ppt吧
sympy 数学相关
极限
| 极限场景 | 代码示例 | 预期结果 |
|---|---|---|
| lim(x→0) sin(x)/x | sp.limit(sp.sin(x)/x, x, 0) | 1 |
| lim(x→0) (1+x)^(1/x) | sp.limit((1+x)**(1/x), x, 0) | e |
| lim(x→∞) (1+a/x)^x | sp.limit((1+a/x)**x, x, sp.oo) | exp(a) |
| lim(x→0) (e^x - 1)/x | sp.limit((sp.exp(x)-1)/x, x, 0) | 1 |
| lim(x→0) ln(1+x)/x | sp.limit(sp.ln(1+x)/x, x, 0) | 1 |
| lim(x→∞) 1/x | sp.limit(1/x, x, sp.oo) | 0 |
| lim(x→0+) 1/x | sp.limit(1/x, x, 0, dir='+') | oo |
| lim(x→0-) 1/x | sp.limit(1/x, x, 0, dir='-') | -oo |
导数
| 操作 | 核心代码 | 说明 |
|---|---|---|
| 一阶导数 | sympy.diff(f, x) 或 f.diff(x) | 对 f(x) 求一阶导数,结果为 d/dx f(x) |
| 二阶导数 | sympy.diff(f, x, x) 或 f.diff(x, 2) | 对 f(x) 求二阶导数,结果为 d²/dx² f(x) |
| 高阶导数 | sympy.diff(f, x, 3) | 对 f(x) 求三阶导数,以此类推 |
| 操作 | 核心代码 | 说明 |
|---|---|---|
| 混合偏导 | g.diff(x, y) | 对 g(x,y) 先求 x 偏导,再求 y 偏导,结果为 ∂²/∂y∂x g(x,y) |
| 高阶混合偏导 | g.diff(x, 3, y, 2) | 对 x 求 3 阶偏导、对 y 求 2 阶偏导,结果为 ∂⁵/∂y²∂x³ g(x,y) |
延迟导数(Derivative)
expr = sympy.exp(sympy.cos(x))
d = sympy.Derivative(expr, x) # 延迟表示导数,不计算
d.doit() # 计算导数,结果为 -exp(cos(x)) * sin(x)
积分
| 操作 | 核心代码 | 说明 |
|---|---|---|
| 不定积分 | sympy.integrate(f, x) | 对 f(x) 求不定积分,结果为 ∫f(x)dx(无常数项) |
| 操作 | 核心代码 | 说明 |
|---|---|---|
| 定积分 | sympy.integrate(f, (x, a, b)) | 对 f(x) 在区间 [a,b] 上求定积分,结果为 ∫ₐᵇf(x)dx |
级数与乘积(Sum / Product)
1. 无穷级数求和(Sum)
n = sympy.symbols("n", integer=True)
sumlist = sympy.Sum(1/(n**2), (n, 1, sympy.oo)) # 定义级数
sumlist.doit() # 计算结果:π²/6
2. 有限 / 无穷乘积(Product)
productlist = sympy.Product(n, (n, 1, 7)) # 定义乘积(1×2×3×…×7)
productlist.doit() # 计算结果:5040(即7!)
import sympy as sp
n, k = sp.symbols("n k", integer=True)
| 功能场景 | 核心代码示例 | 数学表达式 | 输出结果(SymPy 标准格式) |
|---|---|---|---|
| 基础有限整数累乘 | sp.Product(n, (n, 1, 6)).doit() | n=1∏6n | 720 |
| 通用阶乘符号表达式 | sp.Product(k, (k, 1, n)).doit() | k=1∏nk=n! | n! |
| 自定义通项有限乘积 | sp.Product(2*n, (n, 1, 3)).doit() | n=1∏32n | 48 |
| 收敛无穷乘积计算 | sp.Product(1 - 1/n**2, (n, 2, sp.oo)).doit() | n=2∏∞(1−n21) | 21 |
| 延迟乘积表达式构建 | sp.Product((n+1)/n, (n, 1, 10)) | n=1∏10nn+1 | n=1∏10nn+1 |
泰勒级数展开(series)
| 操作 | 核心代码 | 说明 |
|---|---|---|
| 默认展开(x=0,5 阶) | sympy.series(f, x) 或 f.series(x) | 在 x=0 处展开,默认到 O(x⁶) |
| 指定阶数 | sympy.cos(x).series(n=10) | 展开到 O(x¹⁰) |
| 指定展开点 | f.series(x, x0, n=3) | 在 x=x0 处展开到 3 阶 |

浙公网安备 33010602011771号