Sympify () and Eval () equations do not execute inside a function

I am writing a script that reads values ​​from CSV through pandas into a DataFrame. The values ​​"A" and "B" are the inputs to the equation. This equation is obtained from the output XML file from an external program. The equation gives the result for rows "A" and "B" across the rows of the DataFrame and returns those results to the original DataFrame.

If I make a function definition, write an equation explicitly in the definition, and return that equation, everything works fine. eg.

import pandas as pd

dataFrame = pd.read_csv() # Reads CSV to "dataFrame"
A = dataFrame['A'] # Defines A as row A in "dataFrame"
B = dataFrame['B'] # Defines B as row B in "dataFrame"

def Func(a,b):
    P = 2*a+3*b
    return P

outPut['P'] = Func(A, B) # Assigns a value to each row in "outPut" for each 'A' and 'B' per row of "dataFrame"

      

However, what I really want to do is "build" the same equation from the XML file, rather than typing it in explicitly. So, I basically pull the "terms" and "coefficients" from the xml file and end up with a lowercase form of the equation. Then I convert the string to an executable function using sympy.sympify (). eg,

import pandas as pd
import sympy as sy
import xml.etree.ElementTree as etree

dataFrame = pd.read_csv() # Reads CSV to "dataFrame"
A = dataFrame['A']  # Defines A as row A in "dataFrame"
B = dataFrame['B']  # Defines B as row B in "dataFrame"

tree = etree.parse('C:\...')
.
..(some XML stuff with etree)
.
equationString = "some code that grabs terms and coefficients from XML file" # Builds equation from XML  'terms' and 'coefficients'

P = sy.sympify(equationString)

def Func(A, B):
    global P    
    return P

outPut['P'] = Func(A, B) # Assigns a value to each row in "outPut" for each 'A' and 'B' per row of "dataFrame"

      

As a result, when I call to execute this equation on the dataFrame, the literal equation is copied to the "outPut" DF, not the result line by line for each "A" and "B". I don't understand why Python sees these code examples differently and how to achieve the result I want from the first example. For some reason, the result of sympify () is not executable. The same thing happens when I use eval ().

+3


source to share


1 answer


Elaborating on your comment, here's how to fix the problem with lambdify

In [1]: import sympy as sp

In [2]: import pandas as pd

In [3]: import numpy as np

In [4]: df = pd.DataFrame(np.random.randn(5,2), columns=['A', 'B'])

In [5]: equationString = "2*A+3*B"

In [7]: expr = sp.S(equationString)

In [8]: expr
Out[8]: 2*A + 3*B

In [10]: f = sp.lambdify(sp.symbols("A B"), expr, modules="numpy")

In [11]: f(df['A'],df['B'])
Out[11]: 
0   -2.779739
1   -1.176580
2    3.911066
3    1.888639
4    0.745293
dtype: float64

In [12]: 2*df["A"]+3*df["B"] - f(df["A"],df["B"])
Out[12]: 
0    0
1    0
2    0
3    0
4    0
dtype: float64

      



Sympy might be overkill depending on the expressions you see in your xml file. Here's how to useeval

In [1]: import pandas as pd

In [2]: import numpy as np

In [3]: df = pd.DataFrame(np.ran
np.random  np.rank    

In [3]: df = pd.DataFrame(np.random.randn(5, 2), columns=['A', 'B'])

In [4]: equationString = "2*A+3*B"

In [5]: f = eval("lambda A, B: "+equationString)

In [6]: f(df['A'],df['B'])
Out[6]: 
0    1.094797
1   -1.942295
2   -5.181502
3    1.888990
4    3.069017
dtype: float64

In [7]: 2*df["A"]+3*df["B"] - f(df["A"],df["B"])
Out[7]: 
0    0
1    0
2    0
3    0
4    0
dtype: float64

      

+1


source







All Articles