Skip to content

ENH: Raise error writing excel file with a MultiIndexed DataFrame #9794 #9889

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 17, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion doc/source/whatsnew/v0.16.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ Enhancements

- Allow timedelta string conversion when leading zero is missing from time definition, ie `0:00:00` vs `00:00:00`. (:issue:`9570`)

- Trying to write an excel file now raises ``NotImplementedError`` if the ``DataFrame`` has a ``MultiIndex`` instead of writing a broken Excel file. (:issue:`9794`)

.. _whatsnew_0161.api:

API changes
Expand Down Expand Up @@ -137,7 +139,6 @@ Bug Fixes


- Bug in unequal comparisons between categorical data and a scalar, which was not in the categories (e.g. ``Series(Categorical(list("abc"), ordered=True)) > "d"``. This returned ``False`` for all elements, but now raises a ``TypeError``. Equality comparisons also now return ``False`` for ``==`` and ``True`` for ``!=``. (:issue:`9848`)

- Bug in DataFrame ``__setitem__`` when right hand side is a dictionary (:issue:`9874`)
- Bug in ``where`` when dtype is ``datetime64/timedelta64``, but dtype of other is not (:issue:`9804`)
- Bug in ``MultiIndex.sortlevel()`` results in unicode level name breaks (:issue:`9875`)
Expand Down
3 changes: 3 additions & 0 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
71 changes: 46 additions & 25 deletions pandas/io/tests/test_excel.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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()

Expand Down