diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 9b3f2d191831d..ee2ae291cd288 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -2923,8 +2923,10 @@ def union(self, other, sort=None): other, result_name = self._convert_can_do_setop(other) if not is_dtype_equal(self.dtype, other.dtype): - if isinstance(self, ABCMultiIndex) and not is_object_dtype( - unpack_nested_dtype(other) + if ( + isinstance(self, ABCMultiIndex) + and not is_object_dtype(unpack_nested_dtype(other)) + and len(other) > 0 ): raise NotImplementedError( "Can only union MultiIndex with MultiIndex or Index of tuples, " diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index 794f13bbfb6b1..36c8e818f1a24 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -3597,7 +3597,7 @@ def _get_reconciled_name_object(self, other) -> MultiIndex: def _maybe_match_names(self, other): """ Try to find common names to attach to the result of an operation between - a and b. Return a consensus list of names if they match at least partly + a and b. Return a consensus list of names if they match at least partly or list of None if they have completely different names. """ if len(self.names) != len(other.names): diff --git a/pandas/tests/indexes/multi/test_setops.py b/pandas/tests/indexes/multi/test_setops.py index 4a170d9cd161f..0b59e832ce3a8 100644 --- a/pandas/tests/indexes/multi/test_setops.py +++ b/pandas/tests/indexes/multi/test_setops.py @@ -414,6 +414,18 @@ def test_union_empty_self_different_names(): tm.assert_index_equal(result, expected) +def test_union_multiindex_empty_rangeindex(): + # GH#41234 + mi = MultiIndex.from_arrays([[1, 2], [3, 4]], names=["a", "b"]) + ri = pd.RangeIndex(0) + + result_left = mi.union(ri) + tm.assert_index_equal(mi, result_left, check_names=False) + + result_right = ri.union(mi) + tm.assert_index_equal(mi, result_right, check_names=False) + + @pytest.mark.parametrize( "method", ["union", "intersection", "difference", "symmetric_difference"] ) diff --git a/pandas/tests/reshape/concat/test_concat.py b/pandas/tests/reshape/concat/test_concat.py index 2ed38670e88a6..96b88dc61cfed 100644 --- a/pandas/tests/reshape/concat/test_concat.py +++ b/pandas/tests/reshape/concat/test_concat.py @@ -627,3 +627,14 @@ def test_concat_null_object_with_dti(): index=exp_index, ) tm.assert_frame_equal(result, expected) + + +def test_concat_multiindex_with_empty_rangeindex(): + # GH#41234 + mi = MultiIndex.from_tuples([("B", 1), ("C", 1)]) + df1 = DataFrame([[1, 2]], columns=mi) + df2 = DataFrame(index=[1], columns=pd.RangeIndex(0)) + + result = concat([df1, df2]) + expected = DataFrame([[1, 2], [np.nan, np.nan]], columns=mi) + tm.assert_frame_equal(result, expected)