3

I have json file contains arithmetic operation list to apply in dataframe columns, I used eval function , but i could not use eval function due to security issue, how can apply arithmetic operation from json file without using eval function my df function will be like the below table:

a b c d
10 20 40 25
15 10 35 10
25 20 30 100
100 15 35 20
20 25 25 15
10 25 45 30
10 20 40 25
10 20 40 25
json_ops_list= {"1":"a/b",
"2":"a+b+c",
"3": "(a-b)/(b+d)",

"4":"(a-b)/(b*d+c)"}
def calculations(df, json_ops_list):
    final_df = pd.DataFrame()
    for i in json_ops_list:
        col_name = i + '_final'
        final_df[col_name] = df.eval(i)
    return final_df```


petezurich
  • 7,683
  • 8
  • 34
  • 51
  • Does [this help you](https://stackoverflow.com/questions/15197673/using-pythons-eval-vs-ast-literal-eval)? – petezurich Dec 15 '21 at 07:32
  • 1
    [`pd.eval`](https://pandas.pydata.org/docs/reference/api/pandas.eval.html) should not have any security issues because it only supports Python expressions and not all statements. @Mohamed Hassan – Vishnudev Dec 15 '21 at 07:34
  • @Mohamed Hassan - I looking for docs and no information about securty problem. Why do you think there is there problem? – jezrael Dec 15 '21 at 07:37
  • 1
    I think the user is confused with python `eval` and pandas `eval` @jezrael – Vishnudev Dec 15 '21 at 07:38
  • yes, I am confused between python eval and pandas eval – Mohamed Hassan Dec 15 '21 at 07:55

1 Answers1

2

I think security problem is with python eval, in pandas is no this problem:

Neither simple nor compound statements are allowed. This includes things like for, while, and if.

Your solution is necessary change for dictionary:

json_ops_d= {"1":"a/b",
"2":"a+b+c",
"3": "(a-b)/(b+d)",

"4":"(a-b)/(b*d+c)"}

def calculations(df, d):
    final_df = pd.DataFrame()
    for k, v in d.items():
        col_name = k + '_final'
        final_df[col_name] = df.eval(v)
    return final_df

df = calculations(df, json_ops_d)
print (df)
    1_final  2_final   3_final   4_final
0  0.500000       70 -0.222222 -0.018519
1  1.500000       60  0.250000  0.037037
2  1.250000       75  0.041667  0.002463
3  6.666667      150  2.428571  0.253731
4  0.800000       70 -0.125000 -0.012500
5  0.400000       80 -0.272727 -0.018868
6  0.500000       70 -0.222222 -0.018519
7  0.500000       70 -0.222222 -0.018519
jezrael
  • 729,927
  • 78
  • 1,141
  • 1,090