0

I need to evaluate the equations from dataframe using the asteval and uncertainties libraries. I found the way to make it work by iterating over equations and passing each equation separately to the evaluate function. Is there a way to improve efficiency and evaluate all equations together, rather than iterating over each equation? Here is the code:

import numpy as np
import pandas as pd
import uncertainties
from uncertainties import unumpy
import asteval
from uncertainties.umath import *

param = {"Name": ['x', 'alpha', 'y'], 'Value':[5, 1.76, -300], 'Error':[0.001, 0.08, 5]}
df_param = pd.DataFrame(param)
equations = {'Equations':['x*5', 'alpha+3', 'sin(alpha)+5', 'abs(y)']}
df_equation = pd.DataFrame(equations)

aeval = asteval.Interpreter()

result = unumpy.uarray(df_param['Value'], df_param['Error'])

def evaluate(*result, **kwargs):
    _df_param = kwargs.get('df')
    _eq = kwargs.get('eq')
    j=0
    for row in zip(*_df_param.to_dict("list").values()):
        aeval.symtable[row[_df_param.columns.get_loc("Name")]] = result[j]
        j+=1
    return aeval(_eq)

wrap_eval = uncertainties.wrap(evaluate)

j=0
for row in zip(*df_equation.to_dict("list").values()):
    index_list = df_equation.index.to_list()
    equation = row[df_equation.columns.get_loc("Equations")]
    uval = wrap_eval(*result, eq = equation, df=df_param)
    df_equation.loc[index_list[j], 'result'] = uval.nominal_value
    df_equation.loc[index_list[j], 'error'] = uval.std_dev
    j+=1

print(df_equation)

Instead of final for loop in the above code I tried to use the following line:

uval = wrap_eval(*result, eq = df_equation, df=df_param)

and in the evaluate function I changed the return value to:

return aeval(_eq['Equations'])

But it doesn't work and returns an error. Any suggestion how to improve it?

As input to the evaluate function I have two pandas dataframes: one dataframe (df_equations) contains string-based equations that I need to evaluate with uncertainties using the parameters from another pandas dataframe (df_param).

df_equation:

      Equations
0           x*5
1       alpha+3
2  sin(alpha)+5
3        abs(y)

df_param:

    Name   Value  Error
0      x    5.00  0.001
1  alpha    1.76  0.080
2      y -300.00  5.000

For output I need to add a "result" and "error" columns to the df_equation dataframe that will contain the result for the equation evaluation and uncertainty, respectively.

Expected output:

      Equations      result     error
0           x*5   25.000000  0.005000
1       alpha+3    4.760000  0.080000
2  sin(alpha)+5    5.982154  0.015046
3        abs(y)  300.000000  5.000000

  • Use the apply function from the dataframe along with the lambda function, maybe? – Roxy Aug 29 '21 at 18:33
  • Thanks for the suggestion. I tried to return from evaluate function the following code: _eq['Equations'].apply(lambda x: aeval(x)). It works well for the value, but it doesn't return the uncertainties. And I need to have both: the value and the uncertainties. – user16613865 Aug 30 '21 at 07:40
  • It becomes highly tedious if the question lacks the input format and output format. Understanding your requirement is difficult. Could you maybe create a sample example of the issue? – Roxy Aug 30 '21 at 09:06
  • I have edited the question and added the input and expected output formats. – user16613865 Aug 30 '21 at 12:15

0 Answers0