From 9003a58278d5a7688fc7d17fb04aa282bbf810fc Mon Sep 17 00:00:00 2001 From: seljaks <33955366+seljaks@users.noreply.github.com> Date: Wed, 14 Sep 2022 18:45:39 +0200 Subject: [PATCH 1/4] ENH/TST/DOC: Added finalize to DataFrame binary ops, GH28283 --- doc/source/whatsnew/v1.5.0.rst | 1 + pandas/core/frame.py | 2 +- pandas/tests/generic/test_finalize.py | 14 +++++--------- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index d8a319da2065e..4ab8315864bd0 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -1236,6 +1236,7 @@ Metadata ^^^^^^^^ - Fixed metadata propagation in :meth:`DataFrame.melt` (:issue:`28283`) - Fixed metadata propagation in :meth:`DataFrame.explode` (:issue:`28283`) +- Fixed metadata propagation for binary operators on :class:`DataFrame` (:issue:`28283`) - Other diff --git a/pandas/core/frame.py b/pandas/core/frame.py index e471e7efb20ae..429e2fb25ee50 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -7725,7 +7725,7 @@ def _construct_result(self, result) -> DataFrame: ------- DataFrame """ - out = self._constructor(result, copy=False) + out = self._constructor(result, copy=False).__finalize__(self) # Pin columns instead of passing to constructor for compat with # non-unique columns case out.columns = self.columns diff --git a/pandas/tests/generic/test_finalize.py b/pandas/tests/generic/test_finalize.py index dddab05af7341..6a7c9d416da62 100644 --- a/pandas/tests/generic/test_finalize.py +++ b/pandas/tests/generic/test_finalize.py @@ -109,14 +109,13 @@ (pd.DataFrame, frame_data, operator.methodcaller("nlargest", 1, "A")), (pd.DataFrame, frame_data, operator.methodcaller("nsmallest", 1, "A")), (pd.DataFrame, frame_mi_data, operator.methodcaller("swaplevel")), - pytest.param( + ( pd.DataFrame, frame_data, operator.methodcaller("add", pd.DataFrame(*frame_data)), ), - marks=not_implemented_mark, - ), + # TODO: div, mul, etc. pytest.param( ( @@ -539,21 +538,18 @@ def test_finalize_called_eval_numexpr(): (pd.DataFrame({"A": [1]}), pd.Series([1])), ], ) -def test_binops(request, args, annotate, all_arithmetic_functions): - # This generates 326 tests... Is that needed? +def test_binops(request, args, annotate, all_binary_operators): + # This generates 624 tests... Is that needed? left, right = args if annotate == "both" and isinstance(left, int) or isinstance(right, int): return - if isinstance(left, pd.DataFrame) or isinstance(right, pd.DataFrame): - request.node.add_marker(pytest.mark.xfail(reason="not implemented")) - if annotate in {"left", "both"} and not isinstance(left, int): left.attrs = {"a": 1} if annotate in {"left", "both"} and not isinstance(right, int): right.attrs = {"a": 1} - result = all_arithmetic_functions(left, right) + result = all_binary_operators(left, right) assert result.attrs == {"a": 1} From 6d5b8a68b454f2a3dc568d9ff56859ae7b53a360 Mon Sep 17 00:00:00 2001 From: seljaks <33955366+seljaks@users.noreply.github.com> Date: Wed, 14 Sep 2022 19:46:01 +0200 Subject: [PATCH 2/4] ENH/TST/DOC: Added finalize to DataFrame binary ops, GH28283 --- pandas/tests/generic/test_finalize.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/pandas/tests/generic/test_finalize.py b/pandas/tests/generic/test_finalize.py index 6a7c9d416da62..af1a76a6263c7 100644 --- a/pandas/tests/generic/test_finalize.py +++ b/pandas/tests/generic/test_finalize.py @@ -109,13 +109,11 @@ (pd.DataFrame, frame_data, operator.methodcaller("nlargest", 1, "A")), (pd.DataFrame, frame_data, operator.methodcaller("nsmallest", 1, "A")), (pd.DataFrame, frame_mi_data, operator.methodcaller("swaplevel")), - - ( - pd.DataFrame, - frame_data, - operator.methodcaller("add", pd.DataFrame(*frame_data)), - ), - + ( + pd.DataFrame, + frame_data, + operator.methodcaller("add", pd.DataFrame(*frame_data)), + ), # TODO: div, mul, etc. pytest.param( ( From 1efbbcd337891b78ea94efd3e61849ea8ddf3ec0 Mon Sep 17 00:00:00 2001 From: seljaks <33955366+seljaks@users.noreply.github.com> Date: Thu, 15 Sep 2022 11:44:44 +0200 Subject: [PATCH 3/4] TST: fix not implemented tests --- pandas/tests/generic/test_duplicate_labels.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pandas/tests/generic/test_duplicate_labels.py b/pandas/tests/generic/test_duplicate_labels.py index 0546534d91399..c9036958cbd74 100644 --- a/pandas/tests/generic/test_duplicate_labels.py +++ b/pandas/tests/generic/test_duplicate_labels.py @@ -68,9 +68,7 @@ def test_to_frame(self): assert ser.to_frame().flags.allows_duplicate_labels is False @pytest.mark.parametrize("func", ["add", "sub"]) - @pytest.mark.parametrize( - "frame", [False, pytest.param(True, marks=not_implemented)] - ) + @pytest.mark.parametrize("frame", [False, True]) @pytest.mark.parametrize("other", [1, pd.Series([1, 2], name="A")]) def test_binops(self, func, other, frame): df = pd.Series([1, 2], name="A", index=["a", "b"]).set_flags( From ea8482a9623c4b6c332771ca7af14545e0aa9615 Mon Sep 17 00:00:00 2001 From: seljaks <33955366+seljaks@users.noreply.github.com> Date: Fri, 16 Sep 2022 14:00:33 +0200 Subject: [PATCH 4/4] DOC: moved mention to whatsnew 1.6 --- doc/source/whatsnew/v1.5.0.rst | 1 - doc/source/whatsnew/v1.6.0.rst | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index 4ab8315864bd0..d8a319da2065e 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -1236,7 +1236,6 @@ Metadata ^^^^^^^^ - Fixed metadata propagation in :meth:`DataFrame.melt` (:issue:`28283`) - Fixed metadata propagation in :meth:`DataFrame.explode` (:issue:`28283`) -- Fixed metadata propagation for binary operators on :class:`DataFrame` (:issue:`28283`) - Other diff --git a/doc/source/whatsnew/v1.6.0.rst b/doc/source/whatsnew/v1.6.0.rst index 18c9cf165e691..890b98015463a 100644 --- a/doc/source/whatsnew/v1.6.0.rst +++ b/doc/source/whatsnew/v1.6.0.rst @@ -29,6 +29,7 @@ enhancement2 Other enhancements ^^^^^^^^^^^^^^^^^^ - :meth:`Series.add_suffix`, :meth:`DataFrame.add_suffix`, :meth:`Series.add_prefix` and :meth:`DataFrame.add_prefix` support an ``axis`` argument. If ``axis`` is set, the default behaviour of which axis to consider can be overwritten (:issue:`47819`) +- Added metadata propagation for binary operators on :class:`DataFrame` (:issue:`28283`) - .. ---------------------------------------------------------------------------