From 6a79ec3c3d4404f3729534dbfc4d66e4a2cbc324 Mon Sep 17 00:00:00 2001 From: Quang Nguyen Date: Sat, 19 Apr 2025 15:43:20 +0700 Subject: [PATCH 1/5] use same format_index option to format_index_names --- pandas/core/generic.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 884107d4bc6af..8b66c1c080eff 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -3568,6 +3568,7 @@ def _wrap(x, alt_format_): elif formatters is None and float_format is not None: formatters_ = partial(_wrap, alt_format_=lambda v: v) format_index_ = [index_format_, column_format_] + format_index_names_ = [index_format_, column_format_] # Deal with hiding indexes and relabelling column names hide_: list[dict] = [] @@ -3584,6 +3585,7 @@ def _wrap(x, alt_format_): elif isinstance(header, (list, tuple)): relabel_index_.append({"labels": header, "axis": "columns"}) format_index_ = [index_format_] # column_format is overwritten + format_index_names_ = [index_format_] # column_format is overwritten if index is False: hide_.append({"axis": "index"}) @@ -3616,6 +3618,7 @@ def _wrap(x, alt_format_): relabel_index=relabel_index_, format={"formatter": formatters_, **base_format_}, format_index=format_index_, + format_index_names=format_index_names_, render_kwargs=render_kwargs_, ) @@ -3628,6 +3631,7 @@ def _to_latex_via_styler( relabel_index: dict | list[dict] | None = None, format: dict | list[dict] | None = None, format_index: dict | list[dict] | None = None, + format_index_names: dict | list[dict] | None = None, render_kwargs: dict | None = None, ): """ @@ -3672,7 +3676,13 @@ def _to_latex_via_styler( self = cast("DataFrame", self) styler = Styler(self, uuid="") - for kw_name in ["hide", "relabel_index", "format", "format_index"]: + for kw_name in [ + "hide", + "relabel_index", + "format", + "format_index", + "format_index_names", + ]: kw = vars()[kw_name] if isinstance(kw, dict): getattr(styler, kw_name)(**kw) From a1c6275db1af327bdc61f06e311b03b8dd4a4e3e Mon Sep 17 00:00:00 2001 From: Quang Nguyen Date: Sat, 19 Apr 2025 15:46:44 +0700 Subject: [PATCH 2/5] test --- pandas/tests/io/formats/test_to_latex.py | 27 ++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/pandas/tests/io/formats/test_to_latex.py b/pandas/tests/io/formats/test_to_latex.py index 8d46442611719..4f0eab4b7b886 100644 --- a/pandas/tests/io/formats/test_to_latex.py +++ b/pandas/tests/io/formats/test_to_latex.py @@ -824,6 +824,33 @@ def test_to_latex_escape_special_chars(self): ) assert result == expected + def test_to_latex_escape_special_chars_in_index_names(self): + special_characters = ["&", "%", "$", "#", "_", "{", "}", "~", "^", "\\"] + df = DataFrame([special_characters, special_characters]).T.set_index(0) + result = df.to_latex(escape=True) + expected = _dedent( + r""" + \begin{tabular}{ll} + \toprule + & 1 \\ + 0 & \\ + \midrule + \& & \& \\ + \% & \% \\ + \$ & \$ \\ + \# & \# \\ + \_ & \_ \\ + \{ & \{ \\ + \} & \} \\ + \textasciitilde & \textasciitilde \\ + \textasciicircum & \textasciicircum \\ + \textbackslash & \textbackslash \\ + \bottomrule + \end{tabular} + """ + ) + assert result == expected + def test_to_latex_specified_header_special_chars_without_escape(self): # GH 7124 df = DataFrame({"a": [1, 2], "b": ["b1", "b2"]}) From adba9ca23767df7ab95e7f27c18f8de620eabb45 Mon Sep 17 00:00:00 2001 From: Quang Nguyen Date: Sat, 19 Apr 2025 20:03:42 +0700 Subject: [PATCH 3/5] fix test --- pandas/tests/io/formats/test_to_latex.py | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/pandas/tests/io/formats/test_to_latex.py b/pandas/tests/io/formats/test_to_latex.py index 4f0eab4b7b886..697e47fae0000 100644 --- a/pandas/tests/io/formats/test_to_latex.py +++ b/pandas/tests/io/formats/test_to_latex.py @@ -825,26 +825,18 @@ def test_to_latex_escape_special_chars(self): assert result == expected def test_to_latex_escape_special_chars_in_index_names(self): - special_characters = ["&", "%", "$", "#", "_", "{", "}", "~", "^", "\\"] - df = DataFrame([special_characters, special_characters]).T.set_index(0) + index = "&%$#_{}}~^\\" + df = DataFrame({index: [1, 2, 3]}).set_index(index) result = df.to_latex(escape=True) expected = _dedent( r""" - \begin{tabular}{ll} + \begin{tabular}{l} \toprule - & 1 \\ - 0 & \\ - \midrule - \& & \& \\ - \% & \% \\ - \$ & \$ \\ - \# & \# \\ - \_ & \_ \\ - \{ & \{ \\ - \} & \} \\ - \textasciitilde & \textasciitilde \\ - \textasciicircum & \textasciicircum \\ - \textbackslash & \textbackslash \\ + \&\%\$\#\_\{\}\}\textasciitilde \textasciicircum \textbackslash \\ + \midrule + 1 \\ + 2 \\ + 3 \\ \bottomrule \end{tabular} """ From 292b86574c0c7e2c7f9864c294b1524643be5b2b Mon Sep 17 00:00:00 2001 From: Quang Nguyen Date: Sat, 19 Apr 2025 20:04:47 +0700 Subject: [PATCH 4/5] add ref to issues --- pandas/tests/io/formats/test_to_latex.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pandas/tests/io/formats/test_to_latex.py b/pandas/tests/io/formats/test_to_latex.py index 697e47fae0000..84068c0ba0924 100644 --- a/pandas/tests/io/formats/test_to_latex.py +++ b/pandas/tests/io/formats/test_to_latex.py @@ -825,6 +825,9 @@ def test_to_latex_escape_special_chars(self): assert result == expected def test_to_latex_escape_special_chars_in_index_names(self): + # https://github.com/pandas-dev/pandas/issues/61309 + # https://github.com/pandas-dev/pandas/issues/57362 + index = "&%$#_{}}~^\\" df = DataFrame({index: [1, 2, 3]}).set_index(index) result = df.to_latex(escape=True) From 0a39cf9f4a682c209cb24dcbc3a39f6d292f1301 Mon Sep 17 00:00:00 2001 From: Quang Nguyen Date: Sat, 19 Apr 2025 20:05:08 +0700 Subject: [PATCH 5/5] rm blank line --- pandas/tests/io/formats/test_to_latex.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/tests/io/formats/test_to_latex.py b/pandas/tests/io/formats/test_to_latex.py index 84068c0ba0924..e73d00aecebe3 100644 --- a/pandas/tests/io/formats/test_to_latex.py +++ b/pandas/tests/io/formats/test_to_latex.py @@ -827,7 +827,6 @@ def test_to_latex_escape_special_chars(self): def test_to_latex_escape_special_chars_in_index_names(self): # https://github.com/pandas-dev/pandas/issues/61309 # https://github.com/pandas-dev/pandas/issues/57362 - index = "&%$#_{}}~^\\" df = DataFrame({index: [1, 2, 3]}).set_index(index) result = df.to_latex(escape=True)