Search code examples
pythonpandasdataframeeval

Expose built-ins (e.g. `str`) in `pd.eval` or `df.eval`


By default, pandas's eval (both pd.eval and df.eval) captures locals() and globals() and makes them available as names in the expression, if prefixed with @. However, built-ins, such as str, are in neither. How can I expose them, to make them available (I guess with @ as well) in the expressions? The expressions are (trusted) user supplied, so I can't just add the built-ins I need.

To give a concrete example, I'd like to get something like the following to run:

df = pd.DataFrame({'a' : [1, 2, 3, 4]})
res = df.eval('a.astype(@str)', engine='python')

Currently, this fails with: pandas.core.computation.ops.UndefinedVariableError: local variable 'str' is not defined. My current workaround, while testing, is to manually add str to globals().


Solution

  • IIUC, put the type between quotes 'str' :

    res = df.eval("a.astype('str')", engine="python")
    

    Output :

    print(type(res.iat[0])) # <class 'str'>
    
    print(res)
    
    0    1
    1    2
    2    3
    3    4
    Name: a, Length: 4, dtype: object