diff --git a/doc/source/whatsnew/v0.20.3.txt b/doc/source/whatsnew/v0.20.3.txt index 77b3e3bd25740..3d6aba98d4d57 100644 --- a/doc/source/whatsnew/v0.20.3.txt +++ b/doc/source/whatsnew/v0.20.3.txt @@ -55,6 +55,7 @@ Indexing ^^^^^^^^ - Bug in ``Float64Index`` causing an empty array instead of ``None`` to be returned from ``.get(np.nan)`` on a Series whose index did not contain any ``NaN`` s (:issue:`8569`) +- Bug in ``MultiIndex.isin`` causing an error when passing an empty iterable (:issue:`16777`) I/O ^^^ diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index ee18263cca6ab..81eac0ac0684f 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -1129,10 +1129,11 @@ def from_tuples(cls, tuples, sortorder=None, names=None): of iterables """ if len(tuples) == 0: - # I think this is right? Not quite sure... - raise TypeError('Cannot infer number of levels from empty list') - - if isinstance(tuples, (np.ndarray, Index)): + if names is None: + msg = 'Cannot infer number of levels from empty list' + raise TypeError(msg) + arrays = [[]] * len(names) + elif isinstance(tuples, (np.ndarray, Index)): if isinstance(tuples, Index): tuples = tuples._values @@ -2621,8 +2622,9 @@ def _wrap_joined_index(self, joined, other): @Appender(Index.isin.__doc__) def isin(self, values, level=None): if level is None: - return algos.isin(self.values, - MultiIndex.from_tuples(values).values) + values = MultiIndex.from_tuples(values, + names=self.names).values + return algos.isin(self.values, values) else: num = self._get_level_number(level) levs = self.levels[num] diff --git a/pandas/tests/indexes/test_multi.py b/pandas/tests/indexes/test_multi.py index ef8806246c2c5..719cd2f7e01a4 100644 --- a/pandas/tests/indexes/test_multi.py +++ b/pandas/tests/indexes/test_multi.py @@ -1720,6 +1720,13 @@ def test_from_tuples(self): idx = MultiIndex.from_tuples(((1, 2), (3, 4)), names=['a', 'b']) assert len(idx) == 2 + def test_from_tuples_empty(self): + # GH 16777 + result = MultiIndex.from_tuples([], names=['a', 'b']) + expected = MultiIndex.from_arrays(arrays=[[], []], + names=['a', 'b']) + tm.assert_index_equal(result, expected) + def test_argsort(self): result = self.index.argsort() expected = self.index.values.argsort()