Skip to content

Commit

Permalink
BUG: Fix bug in pd.eval when UnaryOp in function (#48511)
Browse files Browse the repository at this point in the history
* Fix bug in pd.eval when negative value in function

* Fix test

* Add whatsnew

* Change name check
  • Loading branch information
yuanx749 authored Sep 14, 2022
1 parent f79ee8a commit 2b2720a
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 2 deletions.
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.6.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ Numeric
Conversion
^^^^^^^^^^
- Bug in constructing :class:`Series` with ``int64`` dtype from a string list raising instead of casting (:issue:`44923`)
- Bug in :meth:`DataFrame.eval` incorrectly raising an ``AttributeError`` when there are negative values in function call (:issue:`46471`)
-

Strings
Expand Down
4 changes: 2 additions & 2 deletions pandas/core/computation/expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ def visit_Call(self, node, side=None, **kwargs):

else:

new_args = [self.visit(arg).value for arg in node.args]
new_args = [self.visit(arg)(self.env) for arg in node.args]

for key in node.keywords:
if not isinstance(key, ast.keyword):
Expand All @@ -704,7 +704,7 @@ def visit_Call(self, node, side=None, **kwargs):
)

if key.arg:
kwargs[key.arg] = self.visit(key.value).value
kwargs[key.arg] = self.visit(key.value)(self.env)

name = self.env.add_tmp(res(*new_args, **kwargs))
return self.term_type(name=name, env=self.env)
Expand Down
14 changes: 14 additions & 0 deletions pandas/tests/computation/test_eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,20 @@ def test_float_comparison_bin_op(self, dtype, expr):
res = df.eval(expr)
assert res.values == np.array([False])

def test_unary_in_function(self):
# GH 46471
df = DataFrame({"x": [0, 1, np.nan]})

result = df.eval("x.fillna(-1)")
expected = df.x.fillna(-1)
# column name becomes None if using numexpr
# only check names when the engine is not numexpr
tm.assert_series_equal(result, expected, check_names=not USE_NUMEXPR)

result = df.eval("x.shift(1, fill_value=-1)")
expected = df.x.shift(1, fill_value=-1)
tm.assert_series_equal(result, expected, check_names=not USE_NUMEXPR)

@pytest.mark.parametrize(
"ex",
(
Expand Down

0 comments on commit 2b2720a

Please sign in to comment.