Похоже, вы хотите сохранить Float высокой точности, но округлить с низкой точностью. Вы можете различать на основе соответствующей точности. Я определил 'eq' как уравнение, которое вы дали выше:
>>> for i in sorted(eq.atoms(Float)):
... print(i._prec, i)
...
27 -1.101318
53 0.235702374092739
30 0.24883285
30 0.25234357
53 0.268994781998603
53 0.525103332486078
27 2.011218
Итак, давайте получим плавающие с низкой точностью в списке:
>>> lp = [i for i in eq.atoms(Float) if i._prec <= 30]
И давайте определим словарь замены, который округляет с точностью до двух знаков после запятой:
>>> reps = {k: k.round(2) for k in lp}
А теперь используйте его для замены этих чисел в eq
>>> eq.subs(reps)
>>> eq.subs(reps)
0.504697156091342*x**0.25 + 0.525103332486078*exp(-Abs(2.01*x - 1.1))
Показатели, которые теперь были одинаковыми, стали причиной объединения двух терминов.
Если вы округлите до двух значащих цифр, вы получите:
>>> reps = {k: k.n(2) for k in lp}
>>> eq.subs(reps)
0.268994781998603*x**0.25 + 0.235702374092739*x**0.25 + 0.525103332486078*exp(-Abs(2.0*x - 1.1))
Термины не объединяются, поскольку эти значения 2-сиг-фиг не совпадают. Преобразование в строку и повторное упрощение будет работать, однако. (Но я бы придерживался версии round
.)
>>> eq2 = _
>>> from sympy import S
>>> S(str(eq2))
0.504697156091342*x**0.25 + 0.525103332486078*exp(-Abs(2.0*x - 1.1))
Чтобы просто заменить числа с плавающей точкой в заданной области выражения, есть много способов разобрать выражение: коэффициенты Mul, постоянные члены of Add, et c ... В комментариях ниже вы говорите, что хотите внести изменения в sin
, sign
, exp
и показатели (Pow
), чтобы что-то подобное могло работать:
>>> from sympy import sin, sign, exp, Pow
>>> eq.replace(
... lambda x: isinstance(x, (sin, sign, exp, Pow)),
... lambda x: x.xreplace(dict([(i,i.round(2)) for i in x.atoms(Float)])))
0.504697156091342*x**0.25 + 0.525103332486078*exp(-Abs(2.01*x - 1.1))