diff --git a/doc/source/whatsnew/v0.18.0.txt b/doc/source/whatsnew/v0.18.0.txt index b3bbc5cf5ef8c..71cf61c8f8f82 100644 --- a/doc/source/whatsnew/v0.18.0.txt +++ b/doc/source/whatsnew/v0.18.0.txt @@ -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 diff --git a/pandas/core/format.py b/pandas/core/format.py index d5b95abb6ad08..101a5e64b65b5 100644 --- a/pandas/core/format.py +++ b/pandas/core/format.py @@ -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 @@ -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 @@ -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): """ @@ -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 @@ -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() diff --git a/pandas/core/frame.py b/pandas/core/frame.py index cd32ff2133cae..449068eff4f43 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -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. @@ -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 @@ -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) @@ -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}. @@ -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 + + .. versionadded:: 0.18.0 + """ if colSpace is not None: # pragma: no cover @@ -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) diff --git a/pandas/tests/test_format.py b/pandas/tests/test_format.py index cb5241c205d03..6772c1ee4b1ee 100644 --- a/pandas/tests/test_format.py +++ b/pandas/tests/test_format.py @@ -760,6 +760,34 @@ def test_to_html_unicode(self): expected = u'\n \n \n \n \n \n \n \n \n \n \n \n \n
A
0\u03c3
' 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 = ('\n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + '
A
06,0
13,1
22,2
') + self.assertEqual(result, expected) + def test_to_html_escaped(self): a = 'str