Python中快速解析数学表达式:大量JSON公式高效求值方案咨询
优化数学公式批量求值的方案
一、Sympy内部优化方案
当前用subs循环求值效率极低,Sympy本身提供了更高效的lambdify方法,能把符号表达式转换成可直接调用的Python/NumPy函数,批量处理数据时速度提升显著,还能减少Decimal转换的额外开销:
1. 转成NumPy批量函数(最快,适合非超高精度场景)
如果不需要Decimal级别的高精度,直接用NumPy数组批量计算,完全避免循环:
from sympy import Symbol, parse_expr, lambdify import numpy as np # 仅解析一次公式(关键:避免重复解析开销) input_sym = Symbol("input") formula = "1015995338000000 - (1.180266595461174895340000000E+28 / (11616850504302 + input * 12.884))" parsed_expr = parse_expr(formula, local_dict={"input": input_sym}) # 生成NumPy兼容的求值函数 numpy_eval = lambdify(input_sym, parsed_expr, modules="numpy") # 批量传入数组,直接得到结果数组 values = np.array([100.0, 200.0, 300.0]) results = numpy_eval(values)
2. 保留Decimal精度的优化
如果必须用Decimal,lambdify可以指定使用decimal模块,避免手动转换字符串:
from decimal import Decimal decimal_eval = lambdify(input_sym, parsed_expr, modules={"Decimal": Decimal}) # 批量处理时尽量减少循环内的重复操作 results_decimal = [decimal_eval(Decimal(v)) for v in values]
二、更快的替代库
如果不需要Sympy的符号运算能力(比如公式固定,仅需数值计算),这些库的速度远胜Sympy:
1. Numexpr - 专门优化数值表达式计算
Numexpr会自动优化表达式并利用多核CPU并行计算,比NumPy更快,尤其是复杂表达式:
import numexpr as ne import numpy as np formula = "1015995338000000 - (1.180266595461174895340000000E+28 / (11616850504302 + input * 12.884))" values = np.array([100.0, 200.0, 300.0]) # 直接传入表达式字符串和参数,批量求值 results = ne.evaluate(formula, local_dict={"input": values})
2. Numba - 编译Python函数为机器码
把求值逻辑写成普通Python函数,用@njit装饰器编译成机器码,循环求值的速度能接近C语言:
from numba import njit import numpy as np @njit # 编译成机器码,仅第一次调用有编译开销 def eval_formula(input_values): results = np.empty_like(input_values) # 提前定义常量,避免循环内重复计算 const1 = 1015995338000000.0 const2 = 1.1802665954611749e28 const3 = 11616850504302.0 const4 = 12.884 for i in range(len(input_values)): denominator = const3 + input_values[i] * const4 results[i] = const1 - (const2 / denominator) return results values = np.array([100.0, 200.0, 300.0]) results = eval_formula(values)
3. PyPy - 替换CPython解释器
如果你的代码以纯Python循环为主,用PyPy运行可以大幅提升速度(注意:部分科学计算库兼容性略差,但纯数值计算场景表现很好)。
三、核心优化原则
- 避免重复解析公式:不管用哪种方案,公式只解析/编译一次,重复使用生成的函数。
- 批量处理优先:尽量用数组批量计算替代单值循环,利用底层库的并行优化。
- 减少高精度开销:如果业务允许,用float64(NumPy)替代Decimal,能带来数量级的速度提升。
内容的提问来源于stack exchange,提问作者Alexey Kholodkov
相关产品推荐
相关产品推荐

