Skip to content

Commit 8c4b559

Browse files
Backport PR #49776 on branch 1.5.x (REGR: arithmetic ops recursion error with midx with different dtypes) (#49782)
Backport PR #49776: REGR: arithmetic ops recursion error with midx with different dtypes Co-authored-by: Patrick Hoefler <[email protected]>
1 parent 1616fb3 commit 8c4b559

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

doc/source/whatsnew/v1.5.2.rst

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Fixed regressions
1515
~~~~~~~~~~~~~~~~~
1616
- Fixed regression in :meth:`MultiIndex.join` for extension array dtypes (:issue:`49277`)
1717
- Fixed regression in :meth:`Series.replace` raising ``RecursionError`` with numeric dtype and when specifying ``value=None`` (:issue:`45725`)
18+
- Fixed regression in arithmetic operations for :class:`DataFrame` with :class:`MultiIndex` columns with different dtypes (:issue:`49769`)
1819
- Fixed regression in :meth:`DataFrame.plot` preventing :class:`~matplotlib.colors.Colormap` instance
1920
from being passed using the ``colormap`` argument if Matplotlib 3.6+ is used (:issue:`49374`)
2021
- Fixed regression in :func:`date_range` returning an invalid set of periods for ``CustomBusinessDay`` frequency and ``start`` date with timezone (:issue:`49441`)

pandas/core/ops/__init__.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,9 @@ def should_reindex_frame_op(
334334
left_uniques = left.columns.unique()
335335
right_uniques = right.columns.unique()
336336
cols = left_uniques.intersection(right_uniques)
337-
if len(cols) and not (cols.equals(left_uniques) and cols.equals(right_uniques)):
337+
if len(cols) and not (
338+
len(cols) == len(left_uniques) and len(cols) == len(right_uniques)
339+
):
338340
# TODO: is there a shortcut available when len(cols) == 0?
339341
return True
340342

pandas/tests/frame/test_arithmetic.py

+20
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,26 @@ def test_binop_other(self, op, value, dtype, switch_numexpr_min_elements):
11351135
expected = op(df, value).dtypes
11361136
tm.assert_series_equal(result, expected)
11371137

1138+
def test_arithmetic_midx_cols_different_dtypes(self):
1139+
# GH#49769
1140+
midx = MultiIndex.from_arrays([Series([1, 2]), Series([3, 4])])
1141+
midx2 = MultiIndex.from_arrays([Series([1, 2], dtype="Int8"), Series([3, 4])])
1142+
left = DataFrame([[1, 2], [3, 4]], columns=midx)
1143+
right = DataFrame([[1, 2], [3, 4]], columns=midx2)
1144+
result = left - right
1145+
expected = DataFrame([[0, 0], [0, 0]], columns=midx)
1146+
tm.assert_frame_equal(result, expected)
1147+
1148+
def test_arithmetic_midx_cols_different_dtypes_different_order(self):
1149+
# GH#49769
1150+
midx = MultiIndex.from_arrays([Series([1, 2]), Series([3, 4])])
1151+
midx2 = MultiIndex.from_arrays([Series([2, 1], dtype="Int8"), Series([4, 3])])
1152+
left = DataFrame([[1, 2], [3, 4]], columns=midx)
1153+
right = DataFrame([[1, 2], [3, 4]], columns=midx2)
1154+
result = left - right
1155+
expected = DataFrame([[-1, 1], [-1, 1]], columns=midx)
1156+
tm.assert_frame_equal(result, expected)
1157+
11381158

11391159
def test_frame_with_zero_len_series_corner_cases():
11401160
# GH#28600

0 commit comments

Comments
 (0)