Skip to content

Commit 3788c65

Browse files
cpcloudjreback
authored andcommitted
BUG: dtype query with negation bug (GH8568)
1 parent 2baaefe commit 3788c65

File tree

3 files changed

+33
-3
lines changed

3 files changed

+33
-3
lines changed

doc/source/v0.15.0.txt

+3
Original file line numberDiff line numberDiff line change
@@ -1121,3 +1121,6 @@ Bug Fixes
11211121
- Bug in ``Series`` that allows it to be indexed by a ``DataFrame`` which has unexpected results. Such indexing is no longer permitted (:issue:`8444`)
11221122
- Bug in item assignment of a ``DataFrame`` with multi-index columns where right-hand-side columns were not aligned (:issue:`7655`)
11231123
- Suppress FutureWarning generated by NumPy when comparing object arrays containing NaN for equality (:issue:`7065`)
1124+
1125+
- Bug in ``DataFrame.eval()`` where the dtype of the ``not`` operator (``~``)
1126+
was not correctly inferred as ``bool``.

pandas/computation/ops.py

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
"""Operator classes for eval.
22
"""
33

4-
import re
54
import operator as op
65
from functools import partial
7-
from itertools import product, islice, chain
86
from datetime import datetime
97

108
import numpy as np
@@ -69,7 +67,6 @@ def evaluate(self, *args, **kwargs):
6967
return self
7068

7169
def _resolve_name(self):
72-
key = self.name
7370
res = self.env.resolve(self.local_name, is_local=self.is_local)
7471
self.update(res)
7572

@@ -491,3 +488,13 @@ def __call__(self, env):
491488

492489
def __unicode__(self):
493490
return com.pprint_thing('{0}({1})'.format(self.op, self.operand))
491+
492+
@property
493+
def return_type(self):
494+
operand = self.operand
495+
if operand.return_type == np.dtype('bool'):
496+
return np.dtype('bool')
497+
if (isinstance(operand, Op) and
498+
(operand.op in _cmp_ops_dict or operand.op in _bool_ops_dict)):
499+
return np.dtype('bool')
500+
return np.dtype('int')

pandas/computation/tests/test_eval.py

+20
Original file line numberDiff line numberDiff line change
@@ -1627,6 +1627,26 @@ def test_inf():
16271627
yield check_inf, engine, parser
16281628

16291629

1630+
def check_negate_lt_eq_le(engine, parser):
1631+
tm.skip_if_no_ne(engine)
1632+
df = pd.DataFrame([[0, 10], [1, 20]], columns=['cat', 'count'])
1633+
expected = df[~(df.cat > 0)]
1634+
1635+
result = df.query('~(cat > 0)', engine=engine, parser=parser)
1636+
tm.assert_frame_equal(result, expected)
1637+
1638+
if parser == 'python':
1639+
with tm.assertRaises(NotImplementedError):
1640+
df.query('not (cat > 0)', engine=engine, parser=parser)
1641+
else:
1642+
result = df.query('not (cat > 0)', engine=engine, parser=parser)
1643+
tm.assert_frame_equal(result, expected)
1644+
1645+
def test_negate_lt_eq_le():
1646+
for engine, parser in product(_engines, expr._parsers):
1647+
yield check_negate_lt_eq_le, engine, parser
1648+
1649+
16301650
if __name__ == '__main__':
16311651
nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],
16321652
exit=False)

0 commit comments

Comments
 (0)