From 7a4c467f2483814a73e795a385587ea7a81901e3 Mon Sep 17 00:00:00 2001 From: Stephan Hoyer Date: Sun, 10 Aug 2014 16:29:10 -0400 Subject: [PATCH] Fix DataFrame.to_latex() with MultiIndex columns Currently, the positioning of \midrule is determined by the number of index levels, not columns levels: >>> print pd.DataFrame({('x', 'y'): ['a']}).to_latex() \begin{tabular}{ll} \toprule {} & x \\ \midrule {} & y \\ 0 & a \\ \bottomrule \end{tabular} The fix is simple: use the number of column levels instead of the number of index levels. --- doc/source/v0.15.0.txt | 2 +- pandas/core/format.py | 2 +- pandas/tests/test_format.py | 25 +++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/doc/source/v0.15.0.txt b/doc/source/v0.15.0.txt index 401cbb6e219f6..81b6c38c74a57 100644 --- a/doc/source/v0.15.0.txt +++ b/doc/source/v0.15.0.txt @@ -429,7 +429,7 @@ Bug Fixes - ``Period`` and ``PeriodIndex`` addition/subtraction with ``np.timedelta64`` results in incorrect internal representations (:issue:`7740`) - +- Bug in ``DataFrame.to_latex`` formatting when columns or index is a ``MultiIndex`` (:issue:`7982`). diff --git a/pandas/core/format.py b/pandas/core/format.py index 8f749d07296a7..41637cf60cc96 100644 --- a/pandas/core/format.py +++ b/pandas/core/format.py @@ -532,7 +532,7 @@ def write(buf, frame, column_format, strcols, longtable=False): buf.write('\\begin{longtable}{%s}\n' % column_format) buf.write('\\toprule\n') - nlevels = frame.index.nlevels + nlevels = frame.columns.nlevels for i, row in enumerate(zip(*strcols)): if i == nlevels: buf.write('\\midrule\n') # End of header diff --git a/pandas/tests/test_format.py b/pandas/tests/test_format.py index 5d785df355aa3..d010222038a09 100644 --- a/pandas/tests/test_format.py +++ b/pandas/tests/test_format.py @@ -2083,6 +2083,31 @@ def test_to_latex(self): """ self.assertEqual(withoutindex_result, withoutindex_expected) + def test_to_latex_multiindex(self): + df = DataFrame({('x', 'y'): ['a']}) + result = df.to_latex() + expected = r"""\begin{tabular}{ll} +\toprule +{} & x \\ +{} & y \\ +\midrule +0 & a \\ +\bottomrule +\end{tabular} +""" + self.assertEqual(result, expected) + + result = df.T.to_latex() + expected = r"""\begin{tabular}{ll} +\toprule +{} & 0 \\ +\midrule +x y & a \\ +\bottomrule +\end{tabular} +""" + self.assertEqual(result, expected) + def test_to_latex_escape(self): a = 'a' b = 'b'