From 870c9d190183bd9f0b6c558e24cfe6fb26d4cfa0 Mon Sep 17 00:00:00 2001 From: yuanx749 Date: Fri, 27 Sep 2024 16:45:46 +0800 Subject: [PATCH 1/4] BUG: pd.eval with engine="numexpr" fails with float division --- pandas/core/computation/align.py | 2 +- pandas/tests/computation/test_eval.py | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/pandas/core/computation/align.py b/pandas/core/computation/align.py index 7de4d8cdf99e1..6158c4f4d0539 100644 --- a/pandas/core/computation/align.py +++ b/pandas/core/computation/align.py @@ -213,7 +213,7 @@ def reconstruct_object(typ, obj, axes, dtype, name): if hasattr(res_t, "type") and typ == np.bool_ and res_t != np.bool_: ret_value = res_t.type(obj) else: - ret_value = typ(obj).astype(res_t) + ret_value = res_t.type(obj) # The condition is to distinguish 0-dim array (returned in case of # scalar) and 1 element array # e.g. np.array(0) and np.array([0]) diff --git a/pandas/tests/computation/test_eval.py b/pandas/tests/computation/test_eval.py index 31d568d7c1e0c..d19e24f3837c2 100644 --- a/pandas/tests/computation/test_eval.py +++ b/pandas/tests/computation/test_eval.py @@ -1998,3 +1998,10 @@ def test_validate_bool_args(value): msg = 'For argument "inplace" expected type bool, received type' with pytest.raises(ValueError, match=msg): pd.eval("2+2", inplace=value) + + +def test_eval_float_div_numexpr(): + # GH59736 + result = pd.eval("1 / 2", engine="numexpr") + expected = 0.5 + assert result == expected From c64b54d25adee292a47b2261938a8a0be28e30df Mon Sep 17 00:00:00 2001 From: yuanx749 Date: Fri, 27 Sep 2024 18:17:36 +0800 Subject: [PATCH 2/4] Add skip --- pandas/tests/computation/test_eval.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/tests/computation/test_eval.py b/pandas/tests/computation/test_eval.py index d19e24f3837c2..c7ff762e7ab70 100644 --- a/pandas/tests/computation/test_eval.py +++ b/pandas/tests/computation/test_eval.py @@ -2000,6 +2000,7 @@ def test_validate_bool_args(value): pd.eval("2+2", inplace=value) +@td.skip_if_no("numexpr") def test_eval_float_div_numexpr(): # GH59736 result = pd.eval("1 / 2", engine="numexpr") From c1d69e0f3b82d934d338be806898de4b450c6645 Mon Sep 17 00:00:00 2001 From: yuanx749 Date: Tue, 1 Oct 2024 09:46:28 +0800 Subject: [PATCH 3/4] Add whatsnew --- doc/source/whatsnew/v3.0.0.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 41ba80989a0ce..c8c96c8a19855 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -697,6 +697,7 @@ Other - Bug in :class:`DataFrame` when passing a ``dict`` with a NA scalar and ``columns`` that would always return ``np.nan`` (:issue:`57205`) - Bug in :func:`eval` on :class:`ExtensionArray` on including division ``/`` failed with a ``TypeError``. (:issue:`58748`) - Bug in :func:`eval` where the names of the :class:`Series` were not preserved when using ``engine="numexpr"``. (:issue:`10239`) +- Bug in :func:`eval` with ``engine="numexpr"`` returning unexpected result for float division. (:issue:`59736`) - Bug in :func:`unique` on :class:`Index` not always returning :class:`Index` (:issue:`57043`) - Bug in :meth:`DataFrame.apply` where passing ``engine="numba"`` ignored ``args`` passed to the applied function (:issue:`58712`) - Bug in :meth:`DataFrame.eval` and :meth:`DataFrame.query` which caused an exception when using NumPy attributes via ``@`` notation, e.g., ``df.eval("@np.floor(a)")``. (:issue:`58041`) From 4645e55f2f60c8d4a0811e5b16aea9cf0a34de05 Mon Sep 17 00:00:00 2001 From: yuanx749 Date: Thu, 3 Oct 2024 22:45:39 +0800 Subject: [PATCH 4/4] update --- pandas/tests/computation/test_eval.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/computation/test_eval.py b/pandas/tests/computation/test_eval.py index c7ff762e7ab70..3c0bf6c35866c 100644 --- a/pandas/tests/computation/test_eval.py +++ b/pandas/tests/computation/test_eval.py @@ -2002,7 +2002,7 @@ def test_validate_bool_args(value): @td.skip_if_no("numexpr") def test_eval_float_div_numexpr(): - # GH59736 + # GH 59736 result = pd.eval("1 / 2", engine="numexpr") expected = 0.5 assert result == expected