Skip to content

ENH decimal parameter to to_latex and to_html, #12031 #12417

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 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/source/whatsnew/v0.18.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,9 @@ Other API Changes

- Statistical functions for ``NDFrame`` objects will now raise if non-numpy-compatible arguments are passed in for ``**kwargs`` (:issue:`12301`)

- ``.to_latex`` and ``.to_html`` gain a ``decimal`` parameter like ``.to_csv``, default ``'.'`` (:issue:`12031`)


.. _whatsnew_0180.deprecations:

Deprecations
Expand Down
9 changes: 5 additions & 4 deletions pandas/core/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ def __init__(self, frame, buf=None, columns=None, col_space=None,
header=True, index=True, na_rep='NaN', formatters=None,
justify=None, float_format=None, sparsify=None,
index_names=True, line_width=None, max_rows=None,
max_cols=None, show_dimensions=False, **kwds):
max_cols=None, show_dimensions=False, decimal='.', **kwds):
self.frame = frame
self.buf = _expand_user(buf) if buf is not None else StringIO()
self.show_index_names = index_names
Expand All @@ -351,6 +351,7 @@ def __init__(self, frame, buf=None, columns=None, col_space=None,
self.float_format = float_format
self.formatters = formatters if formatters is not None else {}
self.na_rep = na_rep
self.decimal = decimal
self.col_space = col_space
self.header = header
self.index = index
Expand Down Expand Up @@ -648,7 +649,7 @@ def _format_col(self, i):
formatter = self._get_formatter(i)
return format_array(frame.iloc[:, i]._values, formatter,
float_format=self.float_format, na_rep=self.na_rep,
space=self.col_space)
space=self.col_space, decimal=self.decimal)

def to_html(self, classes=None, notebook=False):
"""
Expand Down Expand Up @@ -1970,7 +1971,7 @@ def get_formatted_cells(self):


def format_array(values, formatter, float_format=None, na_rep='NaN',
digits=None, space=None, justify='right'):
digits=None, space=None, justify='right', decimal='.'):

if com.is_categorical_dtype(values):
fmt_klass = CategoricalArrayFormatter
Expand Down Expand Up @@ -2000,7 +2001,7 @@ def format_array(values, formatter, float_format=None, na_rep='NaN',

fmt_obj = fmt_klass(values, digits=digits, na_rep=na_rep,
float_format=float_format, formatter=formatter,
space=space, justify=justify)
space=space, justify=justify, decimal=decimal)

return fmt_obj.get_result()

Expand Down
17 changes: 13 additions & 4 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -1497,7 +1497,7 @@ def to_html(self, buf=None, columns=None, col_space=None, colSpace=None,
float_format=None, sparsify=None, index_names=True,
justify=None, bold_rows=True, classes=None, escape=True,
max_rows=None, max_cols=None, show_dimensions=False,
notebook=False):
notebook=False, decimal='.'):
"""
Render a DataFrame as an HTML table.

Expand All @@ -1515,7 +1515,10 @@ def to_html(self, buf=None, columns=None, col_space=None, colSpace=None,
max_cols : int, optional
Maximum number of columns to show before truncating. If None, show
all.
decimal : string, default '.'
Character recognized as decimal separator, e.g. ',' in Europe

.. versionadded:: 0.18.0
"""

if colSpace is not None: # pragma: no cover
Expand All @@ -1533,7 +1536,8 @@ def to_html(self, buf=None, columns=None, col_space=None, colSpace=None,
bold_rows=bold_rows, escape=escape,
max_rows=max_rows,
max_cols=max_cols,
show_dimensions=show_dimensions)
show_dimensions=show_dimensions,
decimal=decimal)
# TODO: a generic formatter wld b in DataFrameFormatter
formatter.to_html(classes=classes, notebook=notebook)

Expand All @@ -1545,7 +1549,7 @@ def to_latex(self, buf=None, columns=None, col_space=None, colSpace=None,
header=True, index=True, na_rep='NaN', formatters=None,
float_format=None, sparsify=None, index_names=True,
bold_rows=True, column_format=None, longtable=None,
escape=None, encoding=None):
escape=None, encoding=None, decimal='.'):
"""
Render a DataFrame to a tabular environment table. You can splice
this into a LaTeX document. Requires \\usepackage{booktabs}.
Expand All @@ -1568,6 +1572,11 @@ def to_latex(self, buf=None, columns=None, col_space=None, colSpace=None,
characters in column names.
encoding : str, default None
Default encoding is ascii in Python 2 and utf-8 in Python 3
decimal : string, default '.'
Character recognized as decimal separator, e.g. ',' in Europe
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


.. versionadded:: 0.18.0

"""

if colSpace is not None: # pragma: no cover
Expand All @@ -1588,7 +1597,7 @@ def to_latex(self, buf=None, columns=None, col_space=None, colSpace=None,
bold_rows=bold_rows,
sparsify=sparsify,
index_names=index_names,
escape=escape)
escape=escape, decimal=decimal)
formatter.to_latex(column_format=column_format, longtable=longtable,
encoding=encoding)

Expand Down
46 changes: 46 additions & 0 deletions pandas/tests/test_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,34 @@ def test_to_html_unicode(self):
expected = u'<table border="1" class="dataframe">\n <thead>\n <tr style="text-align: right;">\n <th></th>\n <th>A</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>\u03c3</td>\n </tr>\n </tbody>\n</table>'
self.assertEqual(df.to_html(), expected)

def test_to_html_decimal(self):
# GH 12031
df = DataFrame({'A': [6.0, 3.1, 2.2]})
result = df.to_html(decimal=',')
expected = ('<table border="1" class="dataframe">\n'
' <thead>\n'
' <tr style="text-align: right;">\n'
' <th></th>\n'
' <th>A</th>\n'
' </tr>\n'
' </thead>\n'
' <tbody>\n'
' <tr>\n'
' <th>0</th>\n'
' <td>6,0</td>\n'
' </tr>\n'
' <tr>\n'
' <th>1</th>\n'
' <td>3,1</td>\n'
' </tr>\n'
' <tr>\n'
' <th>2</th>\n'
' <td>2,2</td>\n'
' </tr>\n'
' </tbody>\n'
'</table>')
self.assertEqual(result, expected)

def test_to_html_escaped(self):
a = 'str<ing1 &amp;'
b = 'stri>ng2 &amp;'
Expand Down Expand Up @@ -2897,6 +2925,24 @@ def test_to_latex_no_header(self):

self.assertEqual(withoutindex_result, withoutindex_expected)

def test_to_latex_decimal(self):
# GH 12031
self.frame.to_latex()
df = DataFrame({'a': [1.0, 2.1], 'b': ['b1', 'b2']})
withindex_result = df.to_latex(decimal=',')
print("WHAT THE")
withindex_expected = r"""\begin{tabular}{lrl}
\toprule
{} & a & b \\
\midrule
0 & 1,0 & b1 \\
1 & 2,1 & b2 \\
\bottomrule
\end{tabular}
"""

self.assertEqual(withindex_result, withindex_expected)

def test_to_csv_quotechar(self):
df = DataFrame({'col': [1, 2]})
expected = """\
Expand Down