Repository: pandas-dev/pandas

Issue:
ERR: raise on mutli-index columns as its not implemented in to_excel
Try to the following code, and you will find column labels mismatched with the data in the Excel file :

`cols = pd.MultiIndex.from_tuples([('site',''),('2014','height'),('2014','weight')])`
`df = pd.DataFrame(np.random.randn(10,3), columns=cols)`
`df.to_excel('test.xlsx', index=False)`

I am using pandas v0.16.0.



Discussion:
this is not implemented for a column multi-index, see #4679 
for either reading or writing

So, going to change this issue to one for error reporting to raise until this is implemented.

I'm starting on this one now


Resolving patch:
diff --git a/pandas/core/frame.py b/pandas/core/frame.py
--- a/pandas/core/frame.py
+++ b/pandas/core/frame.py
@@ -1244,6 +1244,9 @@ def to_excel(self, excel_writer, sheet_name='Sheet1', na_rep='',
         >>> writer.save()
         """
         from pandas.io.excel import ExcelWriter
+        if self.columns.nlevels > 1:
+            raise NotImplementedError("Writing as Excel with a MultiIndex is "
+                                      "not yet implemented.")
 
         need_save = False
         if encoding == None:


Test patch:
diff --git a/pandas/io/tests/test_excel.py b/pandas/io/tests/test_excel.py
--- a/pandas/io/tests/test_excel.py
+++ b/pandas/io/tests/test_excel.py
@@ -1132,31 +1132,29 @@ def roundtrip(df, header=True, parser_hdr=0):
 
         nrows = 5
         ncols = 3
-
-        for i in range(1, 4):  # row multindex upto nlevel=3
-            for j in range(1, 4):  # col ""
-                df = mkdf(nrows, ncols, r_idx_nlevels=i, c_idx_nlevels=j)
-                res = roundtrip(df)
-                # shape
-                self.assertEqual(res.shape, (nrows, ncols + i))
-
-                # no nans
-                for r in range(len(res.index)):
-                    for c in range(len(res.columns)):
-                        self.assertTrue(res.ix[r, c] is not np.nan)
-
-        for i in range(1, 4):  # row multindex upto nlevel=3
-            for j in range(1, 4):  # col ""
-                df = mkdf(nrows, ncols, r_idx_nlevels=i, c_idx_nlevels=j)
-                res = roundtrip(df, False)
-                # shape
-                self.assertEqual(res.shape, (
-                    nrows - 1, ncols + i))  # first row taken as columns
-
-                # no nans
-                for r in range(len(res.index)):
-                    for c in range(len(res.columns)):
-                        self.assertTrue(res.ix[r, c] is not np.nan)
+        for use_headers in (True, False):
+            for i in range(1, 4):  # row multindex upto nlevel=3
+                for j in range(1, 4):  # col ""
+                    df = mkdf(nrows, ncols, r_idx_nlevels=i, c_idx_nlevels=j)
+
+                    #this if will be removed once multi column excel writing
+                    #is implemented for now fixing #9794
+                    if j>1:
+                        with tm.assertRaises(NotImplementedError):
+                            res = roundtrip(df, use_headers)
+                    else:
+                        res = roundtrip(df, use_headers)
+
+                    if use_headers:
+                        self.assertEqual(res.shape, (nrows, ncols + i))
+                    else:
+                        # first row taken as columns
+                        self.assertEqual(res.shape, (nrows - 1, ncols + i))
+
+                    # no nans
+                    for r in range(len(res.index)):
+                        for c in range(len(res.columns)):
+                            self.assertTrue(res.ix[r, c] is not np.nan)
 
         res = roundtrip(DataFrame([0]))
         self.assertEqual(res.shape, (1, 1))
@@ -1394,6 +1392,29 @@ class XlwtTests(ExcelWriterBase, tm.TestCase):
     engine_name = 'xlwt'
     check_skip = staticmethod(_skip_if_no_xlwt)
 
+    def test_excel_raise_not_implemented_error_on_multiindex_columns(self):
+        _skip_if_no_xlwt()
+        #MultiIndex as columns is not yet implemented 9794
+        cols = pd.MultiIndex.from_tuples([('site',''),
+                                          ('2014','height'),
+                                          ('2014','weight')])
+        df = pd.DataFrame(np.random.randn(10,3), columns=cols)
+        with tm.assertRaises(NotImplementedError):
+            with ensure_clean(self.ext) as path:
+                df.to_excel(path, index=False)
+
+    def test_excel_multiindex_index(self):
+        _skip_if_no_xlwt()
+        #MultiIndex as index works so assert no error #9794
+        cols = pd.MultiIndex.from_tuples([('site',''),
+                                          ('2014','height'),
+                                          ('2014','weight')])
+        df = pd.DataFrame(np.random.randn(3,10), index=cols)
+        with ensure_clean(self.ext) as path:
+            df.to_excel(path, index=False)
+
+
+
     def test_to_excel_styleconverter(self):
         _skip_if_no_xlwt()