TypeError with to_html(sparsify=False) and max_cols < len(columns) · Issue #22887 · pandas-dev/pandas (original) (raw)
Code Sample
import pandas as pd arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'], ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']] df = pd.DataFrame(index=arrays, columns=arrays) df.to_html(max_cols=7, sparsify=False)
TypeError Traceback (most recent call last) in () 3 ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']] 4 df = pd.DataFrame(index=arrays, columns=arrays) ----> 5 df.to_html(max_cols=7, sparsify=False)
~\Anaconda3\lib\site-packages\pandas\core\frame.py in to_html(self, buf, columns, col_space, header, index, na_rep, formatters, float_format, sparsify, index_names, justify, bold_rows, classes, escape, max_rows, max_cols, show_dimensions, notebook, decimal, border, table_id) 2032 decimal=decimal, table_id=table_id) 2033 # TODO: a generic formatter wld b in DataFrameFormatter -> 2034 formatter.to_html(classes=classes, notebook=notebook, border=border) 2035 2036 if buf is None:
~\Anaconda3\lib\site-packages\pandas\io\formats\format.py in to_html(self, classes, notebook, border) 749 table_id=self.table_id) 750 if hasattr(self.buf, 'write'): --> 751 html_renderer.write_result(self.buf) 752 elif isinstance(self.buf, compat.string_types): 753 with open(self.buf, 'w') as f:
~\Anaconda3\lib\site-packages\pandas\io\formats\html.py in write_result(self, buf) 177 178 indent += self.indent_delta --> 179 indent = self._write_header(indent) 180 indent = self._write_body(indent) 181
~\Anaconda3\lib\site-packages\pandas\io\formats\html.py in _write_header(self, indent) 279 recs_new[ins_col] = 1 280 records = recs_new --> 281 values = (values[:ins_col] + [u('...')] + 282 values[ins_col:]) 283
TypeError: can only concatenate tuple (not "list") to tuple
Problem description
Code sample adapted from a test that is currently being skipped.
changing:
to:
produces the following output which is equivalent to the expected result of the skipped test.
Expected Output
bar | bar | baz | ... | foo | qux | qux | ||
---|---|---|---|---|---|---|---|---|
one | two | one | ... | two | one | two | ||
bar | one | NaN | NaN | NaN | ... | NaN | NaN | NaN |
bar | two | NaN | NaN | NaN | ... | NaN | NaN | NaN |
baz | one | NaN | NaN | NaN | ... | NaN | NaN | NaN |
baz | two | NaN | NaN | NaN | ... | NaN | NaN | NaN |
foo | one | NaN | NaN | NaN | ... | NaN | NaN | NaN |
foo | two | NaN | NaN | NaN | ... | NaN | NaN | NaN |
qux | one | NaN | NaN | NaN | ... | NaN | NaN | NaN |
qux | two | NaN | NaN | NaN | ... | NaN | NaN | NaN |
tackling the TypeError
explicitly:
values = (values[:ins_col] + [u('...')] + |
---|
to:
values = (values[:ins_col] + (u('...'),) +
values[ins_col:])
produces the following output which is similar to the current behavior of non-truncated DataFrames. Note the absence of spans in the columns Index.
bar | baz | ... | foo | qux | ||||
---|---|---|---|---|---|---|---|---|
one | two | one | ... | two | one | two | ||
bar | one | NaN | NaN | NaN | ... | NaN | NaN | NaN |
bar | two | NaN | NaN | NaN | ... | NaN | NaN | NaN |
baz | one | NaN | NaN | NaN | ... | NaN | NaN | NaN |
baz | two | NaN | NaN | NaN | ... | NaN | NaN | NaN |
foo | one | NaN | NaN | NaN | ... | NaN | NaN | NaN |
foo | two | NaN | NaN | NaN | ... | NaN | NaN | NaN |
qux | one | NaN | NaN | NaN | ... | NaN | NaN | NaN |
qux | two | NaN | NaN | NaN | ... | NaN | NaN | NaN |
Non-truncated DataFrame
import pandas as pd arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'], ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']] df = pd.DataFrame(index=arrays, columns=arrays) print(df.to_html(sparsify=False))
bar | baz | foo | qux | ||||||
---|---|---|---|---|---|---|---|---|---|
one | two | one | two | one | two | one | two | ||
bar | one | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
bar | two | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
baz | one | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
baz | two | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
foo | one | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
foo | two | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
qux | one | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
qux | two | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
Again note the absence of spans in the columns Index.
Non-truncated DataFrame
with:
bar | bar | baz | baz | foo | foo | qux | qux | ||
---|---|---|---|---|---|---|---|---|---|
one | two | one | two | one | two | one | two | ||
bar | one | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
bar | two | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
baz | one | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
baz | two | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
foo | one | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
foo | two | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
qux | one | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
qux | two | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
I assume the current behavior for a non-truncated DataFrame is incorrect.
I assume that the documentation is also incorrect:
sparsify : bool, optional
Set to False for a DataFrame with a hierarchical index to print every multiindex key at each row, default True
should also print every multiindex key for each column.
Output of pd.show_versions()
INSTALLED VERSIONS
commit: None
python: 3.6.5.final.0
python-bits: 64
OS: Windows
OS-release: 10
machine: AMD64
processor: Intel64 Family 6 Model 58 Stepping 9, GenuineIntel
byteorder: little
LC_ALL: None
LANG: None
LOCALE: None.None
pandas: 0.23.0
pytest: 3.5.1
pip: 10.0.1
setuptools: 39.1.0
Cython: 0.28.2
numpy: 1.14.3
scipy: 1.1.0
pyarrow: None
xarray: None
IPython: 6.4.0
sphinx: 1.7.4
patsy: 0.5.0
dateutil: 2.7.3
pytz: 2018.4
blosc: None
bottleneck: 1.2.1
tables: 3.4.3
numexpr: 2.6.5
feather: None
matplotlib: 2.2.2
openpyxl: 2.5.3
xlrd: 1.1.0
xlwt: 1.3.0
xlsxwriter: 1.0.4
lxml: 4.2.1
bs4: 4.6.0
html5lib: 1.0.1
sqlalchemy: 1.2.7
pymysql: None
psycopg2: None
jinja2: 2.10
s3fs: None
fastparquet: None
pandas_gbq: None
pandas_datareader: None