-
-
Notifications
You must be signed in to change notification settings - Fork 18.5k
EHN: add ability to format index and col names to Styler #57880
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
Merged
Merged
Changes from 13 commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
777ce63
add new method to styler
quangngd 3cbe658
add html test
quangngd d214e02
fix type
quangngd 1e3661f
rename to format_index_names
quangngd 9241a1b
Update pandas/io/formats/style_render.py
quangngd d96eac4
Update pandas/io/formats/style_render.py
quangngd ec2d2b3
add tests
quangngd 0636690
Merge branch 'styler_format_names' of github.com:quangngd/pandas into…
quangngd 87ffa4d
add test
quangngd 783269e
more doc
quangngd a644ac1
doc
quangngd d33f58c
Merge branch 'main' into styler_format_names
quangngd 7d396cc
update code_checks
quangngd bcfb5f4
add example
quangngd 1396cfd
update test
quangngd f4806f7
Update pandas/io/formats/style_render.py
quangngd f7d3461
Update pandas/io/formats/style_render.py
quangngd 60e6ef2
update doc
quangngd 1864c59
Merge branch 'styler_format_names' of github.com:quangngd/pandas into…
quangngd f44c8ce
Merge branch 'main' into styler_format_names
quangngd File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -140,9 +140,15 @@ def __init__( | |
self._display_funcs_index: DefaultDict[ # maps (row, level) -> format func | ||
tuple[int, int], Callable[[Any], str] | ||
] = defaultdict(lambda: partial(_default_formatter, precision=precision)) | ||
self._display_funcs_index_names: DefaultDict[ # maps index level -> format func | ||
int, Callable[[Any], str] | ||
] = defaultdict(lambda: partial(_default_formatter, precision=precision)) | ||
self._display_funcs_columns: DefaultDict[ # maps (level, col) -> format func | ||
tuple[int, int], Callable[[Any], str] | ||
] = defaultdict(lambda: partial(_default_formatter, precision=precision)) | ||
self._display_funcs_column_names: DefaultDict[ # maps col level -> format func | ||
int, Callable[[Any], str] | ||
] = defaultdict(lambda: partial(_default_formatter, precision=precision)) | ||
|
||
def _render( | ||
self, | ||
|
@@ -460,6 +466,12 @@ def _generate_col_header_row( | |
] * (self.index.nlevels - sum(self.hide_index_) - 1) | ||
|
||
name = self.data.columns.names[r] | ||
|
||
is_display = name is not None and not self.hide_column_names | ||
value = name if is_display else self.css["blank_value"] | ||
display_value = ( | ||
self._display_funcs_column_names[r](value) if is_display else None | ||
) | ||
column_name = [ | ||
_element( | ||
"th", | ||
|
@@ -468,10 +480,9 @@ def _generate_col_header_row( | |
if name is None | ||
else f"{self.css['index_name']} {self.css['level']}{r}" | ||
), | ||
name | ||
if (name is not None and not self.hide_column_names) | ||
else self.css["blank_value"], | ||
value, | ||
not all(self.hide_index_), | ||
display_value=display_value, | ||
) | ||
] | ||
|
||
|
@@ -553,6 +564,9 @@ def _generate_index_names_row( | |
f"{self.css['index_name']} {self.css['level']}{c}", | ||
self.css["blank_value"] if name is None else name, | ||
not self.hide_index_[c], | ||
display_value=( | ||
None if name is None else self._display_funcs_index_names[c](name) | ||
), | ||
) | ||
for c, name in enumerate(self.data.index.names) | ||
] | ||
|
@@ -1005,6 +1019,7 @@ def format( | |
Returns | ||
------- | ||
Styler | ||
Returns itself for chaining. | ||
|
||
See Also | ||
-------- | ||
|
@@ -1261,6 +1276,7 @@ def format_index( | |
Returns | ||
------- | ||
Styler | ||
Returns itself for chaining. | ||
|
||
See Also | ||
-------- | ||
|
@@ -1425,6 +1441,7 @@ def relabel_index( | |
Returns | ||
------- | ||
Styler | ||
Returns itself for chaining. | ||
|
||
See Also | ||
-------- | ||
|
@@ -1560,6 +1577,121 @@ def alias_(x, value): | |
|
||
return self | ||
|
||
def format_index_names( | ||
self, | ||
formatter: ExtFormatter | None = None, | ||
axis: Axis = 0, | ||
level: Level | list[Level] | None = None, | ||
na_rep: str | None = None, | ||
precision: int | None = None, | ||
decimal: str = ".", | ||
thousands: str | None = None, | ||
escape: str | None = None, | ||
hyperlinks: str | None = None, | ||
) -> StylerRenderer: | ||
r""" | ||
Format the text display value of index names or column names. | ||
|
||
.. versionadded:: TODO | ||
|
||
Parameters | ||
---------- | ||
formatter : str, callable, dict or None | ||
Object to define how values are displayed. See notes. | ||
axis : {0, "index", 1, "columns"} | ||
Whether to apply the formatter to the index or column headers. | ||
level : int, str, list | ||
The level(s) over which to apply the generic formatter. | ||
na_rep : str, optional | ||
Representation for missing values. | ||
If ``na_rep`` is None, no special formatting is applied. | ||
precision : int, optional | ||
Floating point precision to use for display purposes, if not determined by | ||
the specified ``formatter``. | ||
decimal : str, default "." | ||
Character used as decimal separator for floats, complex and integers. | ||
thousands : str, optional, default None | ||
Character used as thousands separator for floats, complex and integers. | ||
escape : str, optional | ||
Use 'html' to replace the characters ``&``, ``<``, ``>``, ``'``, and ``"`` | ||
in cell display string with HTML-safe sequences. | ||
Use 'latex' to replace the characters ``&``, ``%``, ``$``, ``#``, ``_``, | ||
``{``, ``}``, ``~``, ``^``, and ``\`` in the cell display string with | ||
LaTeX-safe sequences. | ||
Escaping is done before ``formatter``. | ||
hyperlinks : {"html", "latex"}, optional | ||
Convert string patterns containing https://, http://, ftp:// or www. to | ||
HTML <a> tags as clickable URL hyperlinks if "html", or LaTeX \href | ||
commands if "latex". | ||
|
||
Returns | ||
------- | ||
Styler | ||
Returns itself for chaining. | ||
|
||
See Also | ||
-------- | ||
Styler.format_index: Format the text display value of index labels | ||
or column headers. | ||
|
||
Notes | ||
----- | ||
This method has a similar signature to :meth:`Styler.format_index`. Since | ||
`names` are generally label based, and often not numeric, the typical features | ||
expected to be more frequently used here are ``escape`` and ``hyperlinks``. | ||
|
||
When using a ``formatter`` string the dtypes must be compatible, otherwise a | ||
`ValueError` will be raised. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you put this in its own Raises
------ section? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. updated |
||
|
||
.. warning:: | ||
`Styler.format_index_names` is ignored when using the output format | ||
`Styler.to_excel`, since Excel and Python have inherrently different | ||
formatting structures. | ||
""" | ||
axis = self.data._get_axis_number(axis) | ||
if axis == 0: | ||
display_funcs_, obj = self._display_funcs_index_names, self.index | ||
else: | ||
display_funcs_, obj = self._display_funcs_column_names, self.columns | ||
levels_ = refactor_levels(level, obj) | ||
|
||
if all( | ||
( | ||
formatter is None, | ||
level is None, | ||
precision is None, | ||
decimal == ".", | ||
thousands is None, | ||
na_rep is None, | ||
escape is None, | ||
hyperlinks is None, | ||
) | ||
): | ||
display_funcs_.clear() | ||
return self # clear the formatter / revert to default and avoid looping | ||
|
||
if not isinstance(formatter, dict): | ||
formatter = {level: formatter for level in levels_} | ||
else: | ||
formatter = { | ||
obj._get_level_number(level): formatter_ | ||
for level, formatter_ in formatter.items() | ||
} | ||
|
||
for lvl in levels_: | ||
format_func = _maybe_wrap_formatter( | ||
formatter.get(lvl), | ||
na_rep=na_rep, | ||
precision=precision, | ||
decimal=decimal, | ||
thousands=thousands, | ||
escape=escape, | ||
hyperlinks=hyperlinks, | ||
) | ||
display_funcs_[lvl] = format_func | ||
|
||
return self | ||
|
||
|
||
def _element( | ||
html_element: str, | ||
|
@@ -1571,7 +1703,7 @@ def _element( | |
""" | ||
Template to return container with information for a <td></td> or <th></th> element. | ||
""" | ||
if "display_value" not in kwargs: | ||
if "display_value" not in kwargs or kwargs["display_value"] is None: | ||
attack68 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
kwargs["display_value"] = value | ||
return { | ||
"type": html_element, | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.