Skip to content

Latex bugs #20032

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

Closed
wants to merge 10 commits into from
14 changes: 6 additions & 8 deletions pandas/io/formats/excel.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ def build_alignment(self, props):
def build_border(self, props):
return {side: {
'style': self._border_style(props.get('border-{side}-style'
.format(side=side)),
.format(side=side)),
props.get('border-{side}-width'
.format(side=side))),
.format(side=side))),
'color': self.color_to_excel(
props.get('border-{side}-color'.format(side=side))),
} for side in ['top', 'right', 'bottom', 'left']}
Expand Down Expand Up @@ -408,9 +408,7 @@ def _format_header_mi(self):
return

columns = self.columns
level_strs = columns.format(sparsify=self.merge_cells, adjoin=False,
names=False)
level_lengths = get_level_lengths(level_strs)
level_lengths = get_level_lengths(columns, sentinel='')
coloffset = 0
lnum = 0

Expand All @@ -436,6 +434,8 @@ def _format_header_mi(self):
header_style)
else:
# Format in legacy format with dots to indicate levels.
level_strs = columns.format(sparsify=self.merge_cells,
adjoin=False, names=False)
for i, values in enumerate(zip(*level_strs)):
v = ".".join(map(pprint_thing, values))
yield ExcelCell(lnum, coloffset + i + 1, v, header_style)
Expand Down Expand Up @@ -560,9 +560,7 @@ def _format_hierarchical_rows(self):

if self.merge_cells:
# Format hierarchical rows as merged cells.
level_strs = self.df.index.format(sparsify=True, adjoin=False,
names=False)
level_lengths = get_level_lengths(level_strs)
level_lengths = get_level_lengths(self.df.index, sentinel='')

for spans, levels, labels in zip(level_lengths,
self.df.index.levels,
Expand Down
57 changes: 32 additions & 25 deletions pandas/io/formats/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from __future__ import print_function
# pylint: disable=W0141
from collections import defaultdict

from pandas.core.dtypes.missing import isna, notna
from pandas.core.dtypes.common import (
Expand Down Expand Up @@ -603,8 +604,8 @@ def to_string(self):
if len(frame.columns) == 0 or len(frame.index) == 0:
info_line = (u('Empty {name}\nColumns: {col}\nIndex: {idx}')
.format(name=type(self.frame).__name__,
col=pprint_thing(frame.columns),
idx=pprint_thing(frame.index)))
col=pprint_thing(frame.columns),
idx=pprint_thing(frame.index)))
text = info_line
else:

Expand Down Expand Up @@ -1545,44 +1546,50 @@ def _binify(cols, line_width):
return bins


def get_level_lengths(levels, sentinel=''):
"""For each index in each level the function returns lengths of indexes.
def get_level_lengths(index, hidden_elements=None, sentinel=None):
"""
Given an index, find the level length for each element.

Parameters
----------
levels : list of lists
List of values on for level.
sentinel : string, optional
Value which states that no new index starts on there.
hidden_elements : list, optional
A list of index positions which should not be visible

Returns
----------
Returns list of maps. For each level returns map of indexes (key is index
in row and value is length of index).
Returns a list of dicts which represent the level lengths -- the key
is the index in a row and the value is length of the index).
"""
if len(levels) == 0:
return []

control = [True for x in levels[0]]

result = []
for level in levels:
last_index = 0
if sentinel is None:
sentinel = com.sentinel_factory()

lengths = {}
for i, key in enumerate(level):
if control[i] and key == sentinel:
pass
else:
control[i] = False
lengths[last_index] = i - last_index
last_index = i
if hidden_elements is None:
hidden_elements = []

lengths[last_index] = len(level) - last_index
levels = index.format(sparsify=sentinel, adjoin=False, names=False)

result.append(lengths)
lengths = []
if index.nlevels == 1:
levels = [levels]

return result
last_label = 0
for i, level in enumerate(levels):
level_spans = defaultdict(int)
for j, key in enumerate(level):
if not get_option('display.multi_sparse'):
level_spans[j] = 1
else:
if key != sentinel:
last_label = j
level_spans[last_label] += (1 if j not in hidden_elements
else 0)
lengths.append({span[0]: span[1]
for span in level_spans.items() if span[1] > 0})
return lengths


def buffer_put_lines(buf, lines):
Expand Down
11 changes: 3 additions & 8 deletions pandas/io/formats/html.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ def _column_header():
sentinel = None
levels = self.columns.format(sparsify=sentinel, adjoin=False,
names=False)
level_lengths = get_level_lengths(levels, sentinel)
level_lengths = get_level_lengths(self.columns, sentinel=sentinel)
inner_lvl = len(level_lengths) - 1
for lnum, (records, values) in enumerate(zip(level_lengths,
levels)):
Expand Down Expand Up @@ -397,12 +397,7 @@ def _write_hierarchical_rows(self, fmt_values, indent):
idx_values = lzip(*idx_values)

if self.fmt.sparsify:
# GH3547
sentinel = com.sentinel_factory()
levels = frame.index.format(sparsify=sentinel, adjoin=False,
names=False)

level_lengths = get_level_lengths(levels, sentinel)
level_lengths = get_level_lengths(frame.index)
inner_lvl = len(level_lengths) - 1
if truncate_v:
# Insert ... row and adjust idx_values and
Expand Down Expand Up @@ -471,7 +466,7 @@ def _write_hierarchical_rows(self, fmt_values, indent):
row.insert(row_levels - sparse_offset +
self.fmt.tr_col_num, '...')
self.write_tr(row, indent, self.indent_delta, tags=tags,
nindex_levels=len(levels) - sparse_offset)
nindex_levels=len(level_lengths) - sparse_offset)
else:
for i in range(len(frame)):
idx_values = list(zip(*frame.index.format(
Expand Down
Loading