From 22d6d10dae83772816c663c577d166763b7e3105 Mon Sep 17 00:00:00 2001 From: jiawei-zhang-a <2992758051@qq.com> Date: Mon, 24 Apr 2023 05:48:31 +0000 Subject: [PATCH 1/5] call finalize in DataFrame.eval with engine=numexpr --- pandas/core/frame.py | 2 +- pandas/tests/generic/test_finalize.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 051ebfff47f83..78e2ec410fcbc 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4596,7 +4596,7 @@ def eval(self, expr: str, *, inplace: bool = False, **kwargs) -> Any | None: kwargs["target"] = self kwargs["resolvers"] = tuple(kwargs.get("resolvers", ())) + resolvers - return _eval(expr, inplace=inplace, **kwargs) + return _eval(expr, inplace=inplace, **kwargs).__finalize__(self, method="eval") def select_dtypes(self, include=None, exclude=None) -> Self: """ diff --git a/pandas/tests/generic/test_finalize.py b/pandas/tests/generic/test_finalize.py index 3c4ea5bd1fb2c..9703d2ced15f3 100644 --- a/pandas/tests/generic/test_finalize.py +++ b/pandas/tests/generic/test_finalize.py @@ -460,7 +460,6 @@ def test_finalize_called(ndframe_method): assert result.attrs == {"a": 1} -@not_implemented_mark def test_finalize_called_eval_numexpr(): pytest.importorskip("numexpr") df = pd.DataFrame({"A": [1, 2]}) From 3e9b8707d08b92404d502d72fcf44d23f3e51e6e Mon Sep 17 00:00:00 2001 From: jiawei-zhang-a <2992758051@qq.com> Date: Wed, 26 Apr 2023 03:34:13 +0000 Subject: [PATCH 2/5] Fix the bug when some case eval method does not have attribute __finalize__ --- pandas/core/frame.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 78e2ec410fcbc..8352c927d1deb 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4596,7 +4596,9 @@ def eval(self, expr: str, *, inplace: bool = False, **kwargs) -> Any | None: kwargs["target"] = self kwargs["resolvers"] = tuple(kwargs.get("resolvers", ())) + resolvers - return _eval(expr, inplace=inplace, **kwargs).__finalize__(self, method="eval") + result = _eval(expr, inplace=inplace, **kwargs) + return result.__finalize__(self, method="eval") if hasattr(result, '__finalize__') else result + def select_dtypes(self, include=None, exclude=None) -> Self: """ From d4e1ed422d59079742525cb9e324f3e7fd5a53a6 Mon Sep 17 00:00:00 2001 From: jiawei-zhang-a <2992758051@qq.com> Date: Wed, 26 Apr 2023 03:41:32 +0000 Subject: [PATCH 3/5] change style --- pandas/core/frame.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 8352c927d1deb..f96fd66fc3ff2 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4597,8 +4597,11 @@ def eval(self, expr: str, *, inplace: bool = False, **kwargs) -> Any | None: kwargs["resolvers"] = tuple(kwargs.get("resolvers", ())) + resolvers result = _eval(expr, inplace=inplace, **kwargs) - return result.__finalize__(self, method="eval") if hasattr(result, '__finalize__') else result - + return ( + result.__finalize__(self, method="eval") + if hasattr(result, "__finalize__") + else result + ) def select_dtypes(self, include=None, exclude=None) -> Self: """ From 30e95f9b9121e73638cc53ed00a3a285b2ff5369 Mon Sep 17 00:00:00 2001 From: jiawei-zhang-a <2992758051@qq.com> Date: Wed, 26 Apr 2023 17:03:27 +0000 Subject: [PATCH 4/5] Special judge for eval if it not numpy.longlong or NoneType, return finalize --- pandas/core/frame.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index f96fd66fc3ff2..30daa60102f9f 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4597,11 +4597,11 @@ def eval(self, expr: str, *, inplace: bool = False, **kwargs) -> Any | None: kwargs["resolvers"] = tuple(kwargs.get("resolvers", ())) + resolvers result = _eval(expr, inplace=inplace, **kwargs) - return ( - result.__finalize__(self, method="eval") - if hasattr(result, "__finalize__") - else result - ) + + if inplace or isinstance(result, np.longlong): + return result + else: + return result.__finalize__(self, method="eval") def select_dtypes(self, include=None, exclude=None) -> Self: """ From 21fc02dfcfe327d06042df479563b8926eb49f2e Mon Sep 17 00:00:00 2001 From: jiawei-zhang-a <2992758051@qq.com> Date: Wed, 26 Apr 2023 18:47:47 +0000 Subject: [PATCH 5/5] Sepecify the engine --- pandas/core/frame.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 30daa60102f9f..ae5d6b3c17423 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4598,10 +4598,13 @@ def eval(self, expr: str, *, inplace: bool = False, **kwargs) -> Any | None: result = _eval(expr, inplace=inplace, **kwargs) - if inplace or isinstance(result, np.longlong): - return result - else: + # Extract the engine from kwargs or use the default value "numexpr" + engine = kwargs.get("engine") + + if engine == "numexpr" and inplace is False: return result.__finalize__(self, method="eval") + else: + return result def select_dtypes(self, include=None, exclude=None) -> Self: """