From 8fe542b73acfc8624c78c5d234b7a0ae6f4d2e52 Mon Sep 17 00:00:00 2001 From: Jeffrey Tratner Date: Sun, 22 Sep 2013 00:55:46 -0400 Subject: [PATCH] ENH: Better string representation for MultiIndex --- doc/source/release.rst | 2 ++ pandas/core/index.py | 40 +++++++++++++++++++++++++++++++++------- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/doc/source/release.rst b/doc/source/release.rst index 8ba0574df97cb..1d29e64860b2d 100644 --- a/doc/source/release.rst +++ b/doc/source/release.rst @@ -131,6 +131,8 @@ Improvements to existing features (:issue:`3441`, :issue:`4933`) - ``pandas`` is now tested with two different versions of ``statsmodels`` (0.4.3 and 0.5.0) (:issue:`4981`). + - Better string representations of ``MultiIndex`` (including ability to roundtrip + via ``repr``). (:issue:`3347`, :issue:`4935`) API Changes ~~~~~~~~~~~ diff --git a/pandas/core/index.py b/pandas/core/index.py index 7f136450daf6e..d488a29182a18 100644 --- a/pandas/core/index.py +++ b/pandas/core/index.py @@ -1,6 +1,6 @@ # pylint: disable=E1101,E1103,W0232 from functools import partial -from pandas.compat import range, zip, lrange, lzip +from pandas.compat import range, zip, lrange, lzip, u from pandas import compat import numpy as np @@ -17,6 +17,10 @@ from pandas.core.common import _values_from_object, is_float, is_integer from pandas.core.config import get_option +# simplify +default_pprint = lambda x: com.pprint_thing(x, escape_chars=('\t', '\r', '\n'), + quote_strings=True) + __all__ = ['Index'] @@ -2052,18 +2056,40 @@ def _array_values(self): def dtype(self): return np.dtype('O') + def __repr__(self): + encoding = get_option('display.encoding') + attrs = [('levels', default_pprint(self.levels)), + ('labels', default_pprint(self.labels))] + if not all(name is None for name in self.names): + attrs.append(('names', default_pprint(self.names))) + if self.sortorder is not None: + attrs.append(('sortorder', default_pprint(self.sortorder))) + + space = ' ' * (len(self.__class__.__name__) + 1) + prepr = (u("\n%s") % space).join([u("%s=%s") % (k, v) + for k, v in attrs]) + res = u("%s(%s)") % (self.__class__.__name__, prepr) + + if not compat.PY3: + # needs to be str in Python 2 + res = res.encode(encoding) + return res + + def __unicode__(self): """ Return a string representation for a particular Index Invoked by unicode(df) in py2 only. Yields a Unicode String in both py2/py3. """ - output = 'MultiIndex\n%s' - - summary = com.pprint_thing(self, escape_chars=('\t', '\r', '\n'), - quote_strings=True) - - return output % summary + rows = self.format(names=True) + max_rows = get_option('display.max_rows') + if len(rows) > max_rows: + spaces = (len(rows[0]) - 3) // 2 + centered = ' ' * spaces + half = max_rows // 2 + rows = rows[:half] + [centered + '...' + centered] + rows[-half:] + return "\n".join(rows) def __len__(self): return len(self.labels[0])