Skip to content

Commit 6260e29

Browse files
committed
Merge pull request #4935 from jtratner/multiindex-smart-repr
ENH: Better string representation for MultiIndex
2 parents ed81ed0 + 8fe542b commit 6260e29

File tree

2 files changed

+35
-7
lines changed

2 files changed

+35
-7
lines changed

doc/source/release.rst

+2
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ Improvements to existing features
131131
(:issue:`3441`, :issue:`4933`)
132132
- ``pandas`` is now tested with two different versions of ``statsmodels``
133133
(0.4.3 and 0.5.0) (:issue:`4981`).
134+
- Better string representations of ``MultiIndex`` (including ability to roundtrip
135+
via ``repr``). (:issue:`3347`, :issue:`4935`)
134136

135137
API Changes
136138
~~~~~~~~~~~

pandas/core/index.py

+33-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# pylint: disable=E1101,E1103,W0232
22
from functools import partial
3-
from pandas.compat import range, zip, lrange, lzip
3+
from pandas.compat import range, zip, lrange, lzip, u
44
from pandas import compat
55
import numpy as np
66

@@ -17,6 +17,10 @@
1717
from pandas.core.common import _values_from_object, is_float, is_integer
1818
from pandas.core.config import get_option
1919

20+
# simplify
21+
default_pprint = lambda x: com.pprint_thing(x, escape_chars=('\t', '\r', '\n'),
22+
quote_strings=True)
23+
2024

2125
__all__ = ['Index']
2226

@@ -2052,18 +2056,40 @@ def _array_values(self):
20522056
def dtype(self):
20532057
return np.dtype('O')
20542058

2059+
def __repr__(self):
2060+
encoding = get_option('display.encoding')
2061+
attrs = [('levels', default_pprint(self.levels)),
2062+
('labels', default_pprint(self.labels))]
2063+
if not all(name is None for name in self.names):
2064+
attrs.append(('names', default_pprint(self.names)))
2065+
if self.sortorder is not None:
2066+
attrs.append(('sortorder', default_pprint(self.sortorder)))
2067+
2068+
space = ' ' * (len(self.__class__.__name__) + 1)
2069+
prepr = (u("\n%s") % space).join([u("%s=%s") % (k, v)
2070+
for k, v in attrs])
2071+
res = u("%s(%s)") % (self.__class__.__name__, prepr)
2072+
2073+
if not compat.PY3:
2074+
# needs to be str in Python 2
2075+
res = res.encode(encoding)
2076+
return res
2077+
2078+
20552079
def __unicode__(self):
20562080
"""
20572081
Return a string representation for a particular Index
20582082
20592083
Invoked by unicode(df) in py2 only. Yields a Unicode String in both py2/py3.
20602084
"""
2061-
output = 'MultiIndex\n%s'
2062-
2063-
summary = com.pprint_thing(self, escape_chars=('\t', '\r', '\n'),
2064-
quote_strings=True)
2065-
2066-
return output % summary
2085+
rows = self.format(names=True)
2086+
max_rows = get_option('display.max_rows')
2087+
if len(rows) > max_rows:
2088+
spaces = (len(rows[0]) - 3) // 2
2089+
centered = ' ' * spaces
2090+
half = max_rows // 2
2091+
rows = rows[:half] + [centered + '...' + centered] + rows[-half:]
2092+
return "\n".join(rows)
20672093

20682094
def __len__(self):
20692095
return len(self.labels[0])

0 commit comments

Comments
 (0)