diff --git a/doc/source/whatsnew/v1.4.4.rst b/doc/source/whatsnew/v1.4.4.rst index 1e7ed256c05ef..96e4ad4321c60 100644 --- a/doc/source/whatsnew/v1.4.4.rst +++ b/doc/source/whatsnew/v1.4.4.rst @@ -19,6 +19,7 @@ Fixed regressions - Fixed regression in :meth:`DataFrame.loc` not updating the cache correctly after values were set (:issue:`47867`) - Fixed regression in :meth:`DataFrame.loc` not aligning index in some cases when setting a :class:`DataFrame` (:issue:`47578`) - Fixed regression in setting ``None`` or non-string value into a ``string``-dtype Series using a mask (:issue:`47628`) +- Fixed regression in :func:`merge` throwing an error when passing a :class:`Series` with a multi-level name (:issue:`47946`) - Fixed regression in :meth:`DataFrame.eval` creating a copy when updating inplace (:issue:`47449`) - diff --git a/pandas/core/reshape/merge.py b/pandas/core/reshape/merge.py index d3ec9fec4640d..554b8d0cc0659 100644 --- a/pandas/core/reshape/merge.py +++ b/pandas/core/reshape/merge.py @@ -672,8 +672,8 @@ def __init__( if _left.columns.nlevels != _right.columns.nlevels: msg = ( "merging between different levels is deprecated and will be removed " - f"in a future version. ({left.columns.nlevels} levels on the left, " - f"{right.columns.nlevels} on the right)" + f"in a future version. ({_left.columns.nlevels} levels on the left, " + f"{_right.columns.nlevels} on the right)" ) # stacklevel chosen to be correct when this is reached via pd.merge # (and not DataFrame.join) diff --git a/pandas/tests/reshape/merge/test_merge.py b/pandas/tests/reshape/merge/test_merge.py index 7e62500df3e8c..13fb8748c5598 100644 --- a/pandas/tests/reshape/merge/test_merge.py +++ b/pandas/tests/reshape/merge/test_merge.py @@ -2155,6 +2155,26 @@ def test_merge_series(on, left_on, right_on, left_index, right_index, nm): ) +def test_merge_series_multilevel(): + # GH#47946 + a = DataFrame( + {"A": [1, 2, 3, 4]}, + index=MultiIndex.from_product([["a", "b"], [0, 1]], names=["outer", "inner"]), + ) + b = Series( + [1, 2, 3, 4], + index=MultiIndex.from_product([["a", "b"], [1, 2]], names=["outer", "inner"]), + name=("B", "C"), + ) + expected = DataFrame( + {"A": [2, 4], ("B", "C"): [1, 3]}, + index=MultiIndex.from_product([["a", "b"], [1]], names=["outer", "inner"]), + ) + with tm.assert_produces_warning(FutureWarning): + result = merge(a, b, on=["outer", "inner"]) + tm.assert_frame_equal(result, expected) + + @pytest.mark.parametrize( "col1, col2, kwargs, expected_cols", [