numexpr
numexpr copied to clipboard
Failed to evaluate simple expression '(a==1)| b'
The follow exception occurs when evaluating a simple expression.
>>> import numexpr as ne
>>> ne.evaluate('(a==1)| b', local_dict={'a': 0, 'b':1})
Traceback (most recent call last):
File "/home/ubuntu/pes/venv/lib/python3.6/site-packages/numexpr/necompiler.py", line 813, in evaluate
compiled_ex = _numexpr_cache[numexpr_key]
KeyError: ('(a==1)| b', (('optimization', 'aggressive'), ('truediv', False)), (('a', <class 'numpy.int64'>), ('b', <class 'numpy.int64'>)))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/ubuntu/pes/venv/lib/python3.6/site-packages/numexpr/necompiler.py", line 816, in evaluate
NumExpr(ex, signature, **context)
File "/home/ubuntu/pes/venv/lib/python3.6/site-packages/numexpr/necompiler.py", line 628, in NumExpr
precompile(ex, signature, context)
File "/home/ubuntu/pes/venv/lib/python3.6/site-packages/numexpr/necompiler.py", line 572, in precompile
ast = typeCompileAst(ast)
File "/home/ubuntu/pes/venv/lib/python3.6/site-packages/numexpr/necompiler.py", line 214, in typeCompileAst
% (ast.value + '_' + retsig + basesig))
NotImplementedError: couldn't find matching opcode for 'or_bbl'
The following expression is okay.
>>> ne.evaluate('(a==1)| (b != 0)', local_dict={'a': 0, 'b':1})
array(True)
Tested with numexpr 2.6.5 with Python 3.6.2
Logical operators (and, or) are only implemented for boolean type variables and not for integer type (even if the values are guaranteed to be always 0 or 1), so you have to somehow cast your integer variable to boolean. Unfortunately in numexpr 2.x there is no explicit casting possible, so you have to resort to comparing the value to cast it. I think this problem is solved by numexpr3 (either by supporting explicit casting or supporting logical operators on integers but I don't remember which).
See also https://github.com/pydata/numexpr/issues/96
Cool. Let's wait for numexpr3. Thank you @gdementen . Should this ticket be closed?
BTW, if it is still useful, you could use where
to write that:
>>> numexpr.evaluate('where((a==1) | (b > 0), 1, 0)', local_dict={'a': 1, 'b':1})
array(1, dtype=int32)
>>> numexpr.evaluate('where((a==1) | (b > 0), 1, 0)', local_dict={'a': 1, 'b':0})
array(1, dtype=int32)
>>> numexpr.evaluate('where((a==1) | (b > 0), 1, 0)', local_dict={'a': 0, 'b':1})
array(1, dtype=int32)
>>> numexpr.evaluate('where((a==1) | (b > 0), 1, 0)', local_dict={'a': 0, 'b':0})
array(0, dtype=int32)
Message to comment on stale issues. If none provided, will not mark issues stale