Выражение можно рассматривать как сумму терминов. Каждый член имеет явный или неявный коэффициент, который можно извлечь с помощью .as_coeff_Mul()
. Отбор этих терминов на основе знака коэффициента даст вам две группы, которые вас интересуют:
>>> from sympy import sift, Add
>>> ispos = lambda x: x.as_coeff_Mul()[0].is_positive
>>> p = -x*y**2/3 + 4*x*y + 3*x - y
>>> pos, neg = sift(Add.make_args(p), ispos, binary=True)
>>> pos
[3*x, 4*x*y]
Чтобы воссоздать фигуры, сложите их вместе:
>>> ppos, pneg = map(Add, (pos, neg))
>>> assert ppos == 3*x + 4*x*y