SymPy - это символическая математическая библиотека для Python. Ваш вопрос может быть решен как:
import pandas as pd
from sympy import Symbol, solve
from sympy.parsing.sympy_parser import parse_expr
data = {'A': [10,20,30],
'B': [20,10,40],
'FX': ["A+B-x","A-B+x","A*B-x"]}
df = pd.DataFrame(data)
x = Symbol("x", real=True)
for index, row in df.iterrows():
F = parse_expr(row['FX'], local_dict={'A': row['A'], 'B': row['B'], 'x':x})
print (row['A'], row['B'], row['FX'], "-->", F, "-->", solve(F, x))
Это выводит:
10 20 A+B-x --> 30 - x --> [30]
20 10 A-B+x --> x + 10 --> [-10]
30 40 A*B-x --> 1200 - x --> [1200]
Обратите внимание, что решение SymPy возвращает список решений. Если вы уверены, что всегда есть только одно решение, просто используйте solve(F, x)[0]
. (Помните, что в отличие от R, Python всегда начинает индексировать с 0.)
С пониманием списка вы можете написать решение в виде:
sol = [ solve(parse_expr(row['FX'], local_dict={'A': row['A'], 'B': row['B'], 'x':x}),
x)[0] for _, row in df.iterrows() ]
Если у вас много столбцов, вы также можете создатьсловарь с циклом: dict({c:row[c] for c in df.columns}, **{'x':x}) )
. Странный синтаксис **
необходим, если вы хотите объединить словари в понимании списка. См. этот пост об объединении словарей.
cols = df.columns # change this if you won't need all columns
sol = [ solve(parse_expr(row['FX'],
local_dict=dict({c:row[c] for c in cols}, **{'x':x}) ),
x)[0].evalf() for _, row in df.iterrows() ]
PS: SymPy обычно сохраняет решения в символической форме, поскольку предпочитает точные выражения. Когда есть, например, дроби или квадратные корни, они не оцениваются сразу. Чтобы получить оцененную форму, используйте evalf()
, как в solve(F, x)[0].evalf()
.