Skip to content

Commit

Permalink
BUG: to_html misses truncation indicators (...) when index=False (#22786
Browse files Browse the repository at this point in the history
)
  • Loading branch information
simonjayhawkins authored and jreback committed Nov 15, 2018
1 parent e50b5fe commit 8af7637
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 16 deletions.
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.24.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1361,6 +1361,7 @@ Notice how we now instead output ``np.nan`` itself instead of a stringified form
- :func:`read_sas()` will correctly parse sas7bdat files with many columns (:issue:`22628`)
- :func:`read_sas()` will correctly parse sas7bdat files with data page types having also bit 7 set (so page type is 128 + 256 = 384) (:issue:`16615`)
- Bug in :meth:`detect_client_encoding` where potential ``IOError`` goes unhandled when importing in a mod_wsgi process due to restricted access to stdout. (:issue:`21552`)
- Bug in :func:`to_html()` with ``index=False`` misses truncation indicators (...) on truncated DataFrame (:issue:`15019`, :issue:`22783`)
- Bug in :func:`DataFrame.to_string()` that broke column alignment when ``index=False`` and width of first column's values is greater than the width of first column's header (:issue:`16839`, :issue:`13032`)
- Bug in :func:`DataFrame.to_string()` that caused representations of :class:`DataFrame` to not take up the whole window (:issue:`22984`)
- Bug in :func:`DataFrame.to_csv` where a single level MultiIndex incorrectly wrote a tuple. Now just the value of the index is written (:issue:`19589`).
Expand Down
35 changes: 19 additions & 16 deletions pandas/io/formats/html.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,8 @@ def _column_header():
align = self.fmt.justify

if truncate_h:
if not self.fmt.index:
row_levels = 0
ins_col = row_levels + self.fmt.tr_col_num
col_row.insert(ins_col, '...')

Expand Down Expand Up @@ -336,15 +338,10 @@ def _write_body(self, indent):
fmt_values[i] = self.fmt._format_col(i)

# write values
if self.fmt.index:
if isinstance(self.frame.index, ABCMultiIndex):
self._write_hierarchical_rows(fmt_values, indent)
else:
self._write_regular_rows(fmt_values, indent)
if self.fmt.index and isinstance(self.frame.index, ABCMultiIndex):
self._write_hierarchical_rows(fmt_values, indent)
else:
for i in range(min(len(self.frame), self.max_rows)):
row = [fmt_values[j][i] for j in range(len(self.columns))]
self.write_tr(row, indent, self.indent_delta, tags=None)
self._write_regular_rows(fmt_values, indent)

indent -= self.indent_delta
self.write('</tbody>', indent)
Expand All @@ -358,29 +355,35 @@ def _write_regular_rows(self, fmt_values, indent):

ncols = len(self.fmt.tr_frame.columns)
nrows = len(self.fmt.tr_frame)
fmt = self.fmt._get_formatter('__index__')
if fmt is not None:
index_values = self.fmt.tr_frame.index.map(fmt)

if self.fmt.index:
fmt = self.fmt._get_formatter('__index__')
if fmt is not None:
index_values = self.fmt.tr_frame.index.map(fmt)
else:
index_values = self.fmt.tr_frame.index.format()
row_levels = 1
else:
index_values = self.fmt.tr_frame.index.format()
row_levels = 0

row = []
for i in range(nrows):

if truncate_v and i == (self.fmt.tr_row_num):
str_sep_row = ['...'] * len(row)
self.write_tr(str_sep_row, indent, self.indent_delta,
tags=None, nindex_levels=1)
tags=None, nindex_levels=row_levels)

row = []
row.append(index_values[i])
if self.fmt.index:
row.append(index_values[i])
row.extend(fmt_values[j][i] for j in range(ncols))

if truncate_h:
dot_col_ix = self.fmt.tr_col_num + 1
dot_col_ix = self.fmt.tr_col_num + row_levels
row.insert(dot_col_ix, '...')
self.write_tr(row, indent, self.indent_delta, tags=None,
nindex_levels=1)
nindex_levels=row_levels)

def _write_hierarchical_rows(self, fmt_values, indent):
template = 'rowspan="{span}" valign="top"'
Expand Down
30 changes: 30 additions & 0 deletions pandas/tests/io/formats/data/gh15019_expected_output.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th>0</th>
<th>1</th>
</tr>
</thead>
<tbody>
<tr>
<td>1.764052</td>
<td>0.400157</td>
</tr>
<tr>
<td>0.978738</td>
<td>2.240893</td>
</tr>
<tr>
<td>...</td>
<td>...</td>
</tr>
<tr>
<td>0.950088</td>
<td>-0.151357</td>
</tr>
<tr>
<td>-0.103219</td>
<td>0.410599</td>
</tr>
</tbody>
</table>
27 changes: 27 additions & 0 deletions pandas/tests/io/formats/data/gh22783_expected_output.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th>0</th>
<th>1</th>
<th>...</th>
<th>3</th>
<th>4</th>
</tr>
</thead>
<tbody>
<tr>
<td>1.764052</td>
<td>0.400157</td>
<td>...</td>
<td>2.240893</td>
<td>1.867558</td>
</tr>
<tr>
<td>-0.977278</td>
<td>0.950088</td>
<td>...</td>
<td>-0.103219</td>
<td>0.410599</td>
</tr>
</tbody>
</table>
45 changes: 45 additions & 0 deletions pandas/tests/io/formats/test_to_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,28 @@
pass


def expected_html(datapath, name):
"""
Read HTML file from formats data directory.
Parameters
----------
datapath : pytest fixture
The datapath fixture injected into a test by pytest.
name : str
The name of the HTML file without the suffix.
Returns
-------
str : contents of HTML file.
"""
filename = '.'.join([name, 'html'])
filepath = datapath('io', 'formats', 'data', filename)
with open(filepath) as f:
html = f.read()
return html.rstrip()


class TestToHTML(object):

def test_to_html_with_col_space(self):
Expand Down Expand Up @@ -1881,6 +1903,29 @@ def test_to_html_multiindex_max_cols(self):
</table>""")
assert result == expected

@pytest.mark.parametrize('index', [False, 0])
def test_to_html_truncation_index_false_max_rows(self, datapath, index):
# GH 15019
data = [[1.764052, 0.400157],
[0.978738, 2.240893],
[1.867558, -0.977278],
[0.950088, -0.151357],
[-0.103219, 0.410599]]
df = pd.DataFrame(data)
result = df.to_html(max_rows=4, index=index)
expected = expected_html(datapath, 'gh15019_expected_output')
assert result == expected

@pytest.mark.parametrize('index', [False, 0])
def test_to_html_truncation_index_false_max_cols(self, datapath, index):
# GH 22783
data = [[1.764052, 0.400157, 0.978738, 2.240893, 1.867558],
[-0.977278, 0.950088, -0.151357, -0.103219, 0.410599]]
df = pd.DataFrame(data)
result = df.to_html(max_cols=4, index=index)
expected = expected_html(datapath, 'gh22783_expected_output')
assert result == expected

def test_to_html_notebook_has_style(self):
df = pd.DataFrame({"A": [1, 2, 3]})
result = df.to_html(notebook=True)
Expand Down

0 comments on commit 8af7637

Please sign in to comment.