diff --git a/doc/source/whatsnew/v1.3.0.rst b/doc/source/whatsnew/v1.3.0.rst index 393866b92771b..497ac68b70019 100644 --- a/doc/source/whatsnew/v1.3.0.rst +++ b/doc/source/whatsnew/v1.3.0.rst @@ -296,6 +296,7 @@ Groupby/resample/rolling Reshaping ^^^^^^^^^ - Bug in :meth:`DataFrame.unstack` with missing levels led to incorrect index names (:issue:`37510`) +- Bug in :func:`join` over :class:`MultiIndex` returned wrong result, when one of both indexes had only one level (:issue:`36909`) - Bug in :func:`concat` incorrectly casting to ``object`` dtype in some cases when one or more of the operands is empty (:issue:`38843`, :issue:`38907`) - diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 2db803e5c1b19..98a5fe52f8473 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -1674,7 +1674,7 @@ def _drop_level_numbers(self, levnums: List[int]): Drop MultiIndex levels by level _number_, not name. """ - if not levnums: + if not levnums and not isinstance(self, ABCMultiIndex): return self if len(levnums) >= self.nlevels: raise ValueError( diff --git a/pandas/tests/indexes/multi/test_drop.py b/pandas/tests/indexes/multi/test_drop.py index f7b1bc4729428..dcb592287733c 100644 --- a/pandas/tests/indexes/multi/test_drop.py +++ b/pandas/tests/indexes/multi/test_drop.py @@ -180,3 +180,11 @@ def test_single_level_drop_partially_missing_elements(): msg = r"labels \['a'\] not found in level" with pytest.raises(KeyError, match=msg): mi.drop([np.nan, 1, "a"], level=0) + + +def test_droplevel_multiindex_one_level(): + # GH#37208 + index = pd.MultiIndex.from_tuples([(2,)], names=("b",)) + result = index.droplevel([]) + expected = pd.Int64Index([2], name="b") + tm.assert_index_equal(result, expected) diff --git a/pandas/tests/reshape/merge/test_join.py b/pandas/tests/reshape/merge/test_join.py index ad07ced2fca66..f64283147764f 100644 --- a/pandas/tests/reshape/merge/test_join.py +++ b/pandas/tests/reshape/merge/test_join.py @@ -815,3 +815,19 @@ def test_join_cross(input_col, output_cols): result = left.join(right, how="cross", lsuffix="_x", rsuffix="_y") expected = DataFrame({output_cols[0]: [1, 1, 3, 3], output_cols[1]: [3, 4, 3, 4]}) tm.assert_frame_equal(result, expected) + + +def test_join_multiindex_one_level(join_type): + # GH#36909 + left = DataFrame( + data={"c": 3}, index=pd.MultiIndex.from_tuples([(1, 2)], names=("a", "b")) + ) + right = DataFrame( + data={"d": 4}, index=pd.MultiIndex.from_tuples([(2,)], names=("b",)) + ) + result = left.join(right, how=join_type) + expected = DataFrame( + {"c": [3], "d": [4]}, + index=pd.MultiIndex.from_tuples([(2, 1)], names=["b", "a"]), + ) + tm.assert_frame_equal(result, expected)