From f89e883d0847c27d106a7cdf890a1e8eadff03ef Mon Sep 17 00:00:00 2001 From: Saravia Rajal Date: Wed, 16 May 2018 11:47:49 +0100 Subject: [PATCH] BUG: to_records() fails for MultiIndex DF (#21064) --- doc/source/whatsnew/v0.24.0.txt | 2 +- pandas/core/frame.py | 8 ++++++- pandas/tests/frame/test_convert_to.py | 32 +++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index 3886b6c142305..5f9e43a158b0f 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 dccc840f5affd..187b885feec88 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 2472022b862bc..e701600b1cda7 100644 --- a/pandas/tests/frame/test_convert_to.py +++ b/pandas/tests/frame/test_convert_to.py @@ -328,3 +328,35 @@ 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 + idx1 = [u'a', u'a', u'b', u'b'] + idx2 = [u'x', u'y', u'x', u'y'] + tup = zip(idx1, idx2) + index = MultiIndex.from_tuples(tup) + random_data = np.random.randn(size, size) + df = DataFrame(random_data, index=index) + + result = df.to_records(index=True) + + col_arrays = [idx1, idx2] + [col for col in random_data.T] + expected = np.rec.fromarrays( + col_arrays, dtype=np.dtype([('level_0', '