diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index 3886b6c142305f..5f9e43a158b0f1 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -131,7 +131,7 @@ Indexing MultiIndex ^^^^^^^^^^ -- +- Bug :func:`to_records` fails for empty MultiIndex DF (:issue:`21064`) - - diff --git a/pandas/core/frame.py b/pandas/core/frame.py index dccc840f5affd2..187b885feec882 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -1392,7 +1392,13 @@ def to_records(self, index=True, convert_datetime64=None): else: if isinstance(self.index, MultiIndex): # array of tuples to numpy cols. copy copy copy - ix_vals = lmap(np.array, zip(*self.index.values)) + tuples = self.index.values + if len(tuples): + ix_vals = lmap(np.array, zip(*tuples)) + else: + # empty MultiIndex DF + ix_vals = [np.array([], dtype=lev.dtype) + for lev in self.index.levels] else: ix_vals = [self.index.values] diff --git a/pandas/tests/frame/test_convert_to.py b/pandas/tests/frame/test_convert_to.py index 2472022b862bc7..425d28e21ee249 100644 --- a/pandas/tests/frame/test_convert_to.py +++ b/pandas/tests/frame/test_convert_to.py @@ -328,3 +328,26 @@ def test_to_dict_index_dtypes(self, into, expected): result = DataFrame.from_dict(result, orient='index')[cols] expected = DataFrame.from_dict(expected, orient='index')[cols] tm.assert_frame_equal(result, expected) + + def test_to_records_with_multiindex(self): + size = 4 + tup = zip(*[['a', 'a', 'b', 'b'], ['x', 'y', 'x', 'y']]) + index = MultiIndex.from_tuples(tup) + df = DataFrame(np.random.randn(size, size), index=index) + + records = df.to_records(index=True) + assert len(records) == size + # first record includes index + assert records[0][0] == 'a' + assert records[0][1] == 'x' + # last record includes index + assert records[size - 1][0] == 'b' + assert records[size - 1][1] == 'y' + + def test_to_records_with_empty_multiindex(self): + # GH 21064 + multi = MultiIndex([['a'], ['b']], labels=[[], []]) + df = DataFrame(columns=['A'], index=multi) + + records = df.to_records(index=True) + assert len(records) == 0