DataFrame.eval errors with AttributeError: 'UnaryOp'
See original GitHub issueCode Sample, a copy-pastable example if possible
def test_unary():
df = pd.DataFrame({'x': np.array([0.11, 0], dtype=np.float32)})
res = df.eval('(x > 0.1) | (x < -0.1)')
assert np.array_equal(res, np.array([True, False])), res
Problem description
This is related to #11235. on python 3.6, pandas 20.1, this raises an error the traceback ends with:
File ".../envs/py3/lib/python3.6/site-packages/pandas/core/computation/expr.py", line 370, in _maybe_downcast_constants
name = self.env.add_tmp(np.float32(right.value))
AttributeError: 'UnaryOp' object has no attribute 'value'
In that case the right is -(0.1)
INSTALLED VERSIONS
------------------
commit: None
python: 3.6.1.final.0
python-bits: 64
OS: Linux
OS-release: 4.8.0-49-generic
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8
LOCALE: en_US.UTF-8
pandas: 0.20.1 pytest: None pip: 9.0.1 setuptools: 27.2.0 Cython: 0.25.2 numpy: 1.12.1 scipy: 0.19.0 xarray: None IPython: 6.0.0 sphinx: None patsy: None dateutil: 2.6.0 pytz: 2017.2 blosc: None bottleneck: None tables: None numexpr: None feather: None matplotlib: 2.0.2 openpyxl: None xlrd: None xlwt: None xlsxwriter: None lxml: None bs4: None html5lib: None sqlalchemy: None pymysql: None psycopg2: None jinja2: None s3fs: None pandas_gbq: None pandas_datareader: None
Another example:
>>> df = pd.DataFrame({'x':[1,2,3,4,5]})
>>> df.eval('x.shift(-1)')
Issue Analytics
- State:
- Created 6 years ago
- Reactions:4
- Comments:23 (6 by maintainers)
Top Results From Across the Web
'UnaryOp' object has no attribute 'evaluate' when using eval ...
I can't reproduce your error with pandas '1.0.5' . It is working for me with the data you provided. Check your pandas version...
Read more >'UnaryOp' object has no attribute 'evaluate' when using eval ...
Coding example for the question AttributeError: 'UnaryOp' object has no attribute 'evaluate' when using eval function in Python.
Read more >pandas.eval — pandas 1.5.2 documentation
Evaluate a Python expression as a string using various backends. The following arithmetic operations are supported: + , - , * , / ......
Read more >ast — Abstract Syntax Trees — Python 3.11.1 documentation
If there are keyword arguments, they will set the attributes of the same names to the given values. For example, to create and...
Read more >Bug in Zipline? - Technical Help - QuantRocket Support Forum
... .8/site-packages/pandas/core/computation/eval.py", line 342, in eval ... in evaluate left = self.lhs.evaluate( AttributeError: 'UnaryOp' ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I ran into this recently and would like to help with a patch. As best I can tell, the problem is that
_maybe_downcast_constants
not only tries to downcast constants but alsoUnaryOp
’s, which isn’t possible, sinceUnaryOp
instances don’t have avalue
attribute like constants/scalars do.I am new to the pandas code, and the expressions code is a bit tricky, but I think we could catch the
AttributeError
in_maybe_downcast_constants
or explicitly check in each case thatleft
orright
has the attributevalue
.In short, the problem is that an operation like
df.eval(x < -.1)
fails whenx
is anp.float32
because the right side of the equation is seen as aUnaryOp
node instead of as anp.float32
and is subjected to_maybe_downcast_constants
byvisit_BinOp
. OTOH,df.eval(x < @y)
works wheny = -.1
, because pandas doesn’t have to parse it. I think a small change might fix this, but I could be overlooking something bigger and would appreciate feedback.Hi, I am wondering if this is resolved? I’m running into a similar issue using pandas df.query() with negative numbers. Thank you!