Skip to content

Commit 3038c6e

Browse files
authored
ENH: added finalize to binary operators on DataFrame, GH28283 (#48551)
* ENH/TST/DOC: Added finalize to DataFrame binary ops, GH28283 * ENH/TST/DOC: Added finalize to DataFrame binary ops, GH28283 * TST: fix not implemented tests * DOC: moved mention to whatsnew 1.6
1 parent d8fb17c commit 3038c6e

File tree

4 files changed

+10
-17
lines changed

4 files changed

+10
-17
lines changed

doc/source/whatsnew/v1.6.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Other enhancements
3232
- :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`)
3333
- :func:`assert_frame_equal` now shows the first element where the DataFrames differ, analogously to ``pytest``'s output (:issue:`47910`)
3434
- Added ``index`` parameter to :meth:`DataFrame.to_dict` (:issue:`46398`)
35+
- Added metadata propagation for binary operators on :class:`DataFrame` (:issue:`28283`)
3536
-
3637

3738
.. ---------------------------------------------------------------------------

pandas/core/frame.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -7711,7 +7711,7 @@ def _construct_result(self, result) -> DataFrame:
77117711
-------
77127712
DataFrame
77137713
"""
7714-
out = self._constructor(result, copy=False)
7714+
out = self._constructor(result, copy=False).__finalize__(self)
77157715
# Pin columns instead of passing to constructor for compat with
77167716
# non-unique columns case
77177717
out.columns = self.columns

pandas/tests/generic/test_duplicate_labels.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,7 @@ def test_to_frame(self):
6868
assert ser.to_frame().flags.allows_duplicate_labels is False
6969

7070
@pytest.mark.parametrize("func", ["add", "sub"])
71-
@pytest.mark.parametrize(
72-
"frame", [False, pytest.param(True, marks=not_implemented)]
73-
)
71+
@pytest.mark.parametrize("frame", [False, True])
7472
@pytest.mark.parametrize("other", [1, pd.Series([1, 2], name="A")])
7573
def test_binops(self, func, other, frame):
7674
df = pd.Series([1, 2], name="A", index=["a", "b"]).set_flags(

pandas/tests/generic/test_finalize.py

+7-13
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,10 @@
109109
(pd.DataFrame, frame_data, operator.methodcaller("nlargest", 1, "A")),
110110
(pd.DataFrame, frame_data, operator.methodcaller("nsmallest", 1, "A")),
111111
(pd.DataFrame, frame_mi_data, operator.methodcaller("swaplevel")),
112-
pytest.param(
113-
(
114-
pd.DataFrame,
115-
frame_data,
116-
operator.methodcaller("add", pd.DataFrame(*frame_data)),
117-
),
118-
marks=not_implemented_mark,
112+
(
113+
pd.DataFrame,
114+
frame_data,
115+
operator.methodcaller("add", pd.DataFrame(*frame_data)),
119116
),
120117
# TODO: div, mul, etc.
121118
pytest.param(
@@ -539,21 +536,18 @@ def test_finalize_called_eval_numexpr():
539536
(pd.DataFrame({"A": [1]}), pd.Series([1])),
540537
],
541538
)
542-
def test_binops(request, args, annotate, all_arithmetic_functions):
543-
# This generates 326 tests... Is that needed?
539+
def test_binops(request, args, annotate, all_binary_operators):
540+
# This generates 624 tests... Is that needed?
544541
left, right = args
545542
if annotate == "both" and isinstance(left, int) or isinstance(right, int):
546543
return
547544

548-
if isinstance(left, pd.DataFrame) or isinstance(right, pd.DataFrame):
549-
request.node.add_marker(pytest.mark.xfail(reason="not implemented"))
550-
551545
if annotate in {"left", "both"} and not isinstance(left, int):
552546
left.attrs = {"a": 1}
553547
if annotate in {"left", "both"} and not isinstance(right, int):
554548
right.attrs = {"a": 1}
555549

556-
result = all_arithmetic_functions(left, right)
550+
result = all_binary_operators(left, right)
557551
assert result.attrs == {"a": 1}
558552

559553

0 commit comments

Comments
 (0)