Skip to content

Commit 96d22d4

Browse files
authored
MultiIndex union/intersection with non-object other (#32646)
1 parent 5351732 commit 96d22d4

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

pandas/core/indexes/multi.py

+18-4
Original file line numberDiff line numberDiff line change
@@ -3243,9 +3243,13 @@ def union(self, other, sort=None):
32433243

32443244
# TODO: Index.union returns other when `len(self)` is 0.
32453245

3246-
uniq_tuples = lib.fast_unique_multiple(
3247-
[self._values, other._ndarray_values], sort=sort
3248-
)
3246+
if not is_object_dtype(other.dtype):
3247+
raise NotImplementedError(
3248+
"Can only union MultiIndex with MultiIndex or Index of tuples, "
3249+
"try mi.to_flat_index().union(other) instead."
3250+
)
3251+
3252+
uniq_tuples = lib.fast_unique_multiple([self._values, other._values], sort=sort)
32493253

32503254
return MultiIndex.from_arrays(
32513255
zip(*uniq_tuples), sortorder=0, names=result_names
@@ -3279,8 +3283,18 @@ def intersection(self, other, sort=False):
32793283
if self.equals(other):
32803284
return self
32813285

3286+
if not is_object_dtype(other.dtype):
3287+
# The intersection is empty
3288+
# TODO: we have no tests that get here
3289+
return MultiIndex(
3290+
levels=self.levels,
3291+
codes=[[]] * self.nlevels,
3292+
names=result_names,
3293+
verify_integrity=False,
3294+
)
3295+
32823296
lvals = self._values
3283-
rvals = other._ndarray_values
3297+
rvals = other._values
32843298

32853299
uniq_tuples = None # flag whether _inner_indexer was succesful
32863300
if self.is_monotonic and other.is_monotonic:

pandas/tests/indexes/multi/test_setops.py

+13
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ def test_union(idx, sort):
246246
the_union = idx.union(idx[:0], sort=sort)
247247
assert the_union is idx
248248

249+
# FIXME: dont leave commented-out
249250
# won't work in python 3
250251
# tuples = _index.values
251252
# result = _index[:4] | tuples[4:]
@@ -282,6 +283,7 @@ def test_intersection(idx, sort):
282283
expected = idx[:0]
283284
assert empty.equals(expected)
284285

286+
# FIXME: dont leave commented-out
285287
# can't do in python 3
286288
# tuples = _index.values
287289
# result = _index & tuples
@@ -351,6 +353,17 @@ def test_union_sort_other_incomparable_sort():
351353
idx.union(idx[:1], sort=True)
352354

353355

356+
def test_union_non_object_dtype_raises():
357+
# GH#32646 raise NotImplementedError instead of less-informative error
358+
mi = pd.MultiIndex.from_product([["a", "b"], [1, 2]])
359+
360+
idx = mi.levels[1]
361+
362+
msg = "Can only union MultiIndex with MultiIndex or Index of tuples"
363+
with pytest.raises(NotImplementedError, match=msg):
364+
mi.union(idx)
365+
366+
354367
@pytest.mark.parametrize(
355368
"method", ["union", "intersection", "difference", "symmetric_difference"]
356369
)

0 commit comments

Comments
 (0)