Skip to content

Commit

Permalink
BUG: Fix MI repr with long names (pandas-dev#21655)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomAugspurger authored and victor committed Sep 30, 2018
1 parent 8c297ca commit 55463df
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 3 deletions.
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.23.2.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Fixed Regressions
- Fixed regression in :meth:`to_csv` when handling file-like object incorrectly (:issue:`21471`)
- Re-allowed duplicate level names of a ``MultiIndex``. Accessing a level that has a duplicate name by name still raises an error (:issue:`19029`).
- Bug in both :meth:`DataFrame.first_valid_index` and :meth:`Series.first_valid_index` raised for a row index having duplicate values (:issue:`21441`)
- Fixed printing of DataFrames with hierarchical columns with long names (:issue:`21180`)
- Fixed regression in :meth:`~DataFrame.reindex` and :meth:`~DataFrame.groupby`
with a MultiIndex or multiple keys that contains categorical datetime-like values (:issue:`21390`).
- Fixed regression in unary negative operations with object dtype (:issue:`21380`)
Expand Down
10 changes: 7 additions & 3 deletions pandas/io/formats/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -636,10 +636,14 @@ def to_string(self):
mid = int(round(n_cols / 2.))
mid_ix = col_lens.index[mid]
col_len = col_lens[mid_ix]
adj_dif -= (col_len + 1) # adjoin adds one
# adjoin adds one
adj_dif -= (col_len + 1)
col_lens = col_lens.drop(mid_ix)
n_cols = len(col_lens)
max_cols_adj = n_cols - self.index # subtract index column
# subtract index column
max_cols_adj = n_cols - self.index
# GH-21180. Ensure that we print at least two.
max_cols_adj = max(max_cols_adj, 2)
self.max_cols_adj = max_cols_adj

# Call again _chk_truncate to cut frame appropriately
Expand Down Expand Up @@ -778,7 +782,7 @@ def space_format(x, y):

str_columns = list(zip(*[[space_format(x, y) for y in x]
for x in fmt_columns]))
if self.sparsify:
if self.sparsify and len(str_columns):
str_columns = _sparsify(str_columns)

str_columns = [list(x) for x in zip(*str_columns)]
Expand Down
38 changes: 38 additions & 0 deletions pandas/tests/io/formats/test_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,44 @@ def test_repr_non_interactive(self):
assert not has_truncated_repr(df)
assert not has_expanded_repr(df)

def test_repr_truncates_terminal_size(self):
# https://github.com/pandas-dev/pandas/issues/21180
# TODO: use mock fixutre.
# This is being backported, so doing it directly here.
try:
from unittest import mock
except ImportError:
mock = pytest.importorskip("mock")

terminal_size = (118, 96)
p1 = mock.patch('pandas.io.formats.console.get_terminal_size',
return_value=terminal_size)
p2 = mock.patch('pandas.io.formats.format.get_terminal_size',
return_value=terminal_size)

index = range(5)
columns = pd.MultiIndex.from_tuples([
('This is a long title with > 37 chars.', 'cat'),
('This is a loooooonger title with > 43 chars.', 'dog'),
])
df = pd.DataFrame(1, index=index, columns=columns)

with p1, p2:
result = repr(df)

h1, h2 = result.split('\n')[:2]
assert 'long' in h1
assert 'loooooonger' in h1
assert 'cat' in h2
assert 'dog' in h2

# regular columns
df2 = pd.DataFrame({"A" * 41: [1, 2], 'B' * 41: [1, 2]})
with p1, p2:
result = repr(df2)

assert df2.columns[0] in result.split('\n')[0]

def test_repr_max_columns_max_rows(self):
term_width, term_height = get_terminal_size()
if term_width < 10 or term_height < 10:
Expand Down

0 comments on commit 55463df

Please sign in to comment.