-
-
Notifications
You must be signed in to change notification settings - Fork 18.5k
EHN: to_{html, string} col_space col specific #32903
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
Changes from all commits
5b9a825
d2a8ba8
e5549e0
1ce2230
8cbb758
5eabdcb
02d9fcd
f266310
0951dd3
3ad9422
e1e0c90
8c0d05c
b90b55f
11cc0db
3c53daf
6d390b4
9d8fe9e
aefe519
788e0f2
7323e80
7d14cff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,7 +38,7 @@ | |
from pandas._libs.tslib import format_array_from_datetime | ||
from pandas._libs.tslibs import NaT, Timedelta, Timestamp, iNaT | ||
from pandas._libs.tslibs.nattype import NaTType | ||
from pandas._typing import FilePathOrBuffer | ||
from pandas._typing import FilePathOrBuffer, Label | ||
from pandas.errors import AbstractMethodError | ||
|
||
from pandas.core.dtypes.common import ( | ||
|
@@ -77,6 +77,10 @@ | |
List[Callable], Tuple[Callable, ...], Mapping[Union[str, int], Callable] | ||
] | ||
FloatFormatType = Union[str, Callable, "EngFormatter"] | ||
ColspaceType = Mapping[Label, Union[str, int]] | ||
ColspaceArgType = Union[ | ||
str, int, Sequence[Union[str, int]], Mapping[Label, Union[str, int]], | ||
] | ||
|
||
common_docstring = """ | ||
Parameters | ||
|
@@ -530,11 +534,13 @@ class DataFrameFormatter(TableFormatter): | |
__doc__ = __doc__ if __doc__ else "" | ||
__doc__ += common_docstring + return_docstring | ||
|
||
col_space: ColspaceType | ||
|
||
def __init__( | ||
self, | ||
frame: "DataFrame", | ||
columns: Optional[Sequence[str]] = None, | ||
col_space: Optional[Union[str, int]] = None, | ||
col_space: Optional[ColspaceArgType] = None, | ||
header: Union[bool, Sequence[str]] = True, | ||
index: bool = True, | ||
na_rep: str = "NaN", | ||
|
@@ -574,7 +580,27 @@ def __init__( | |
) | ||
self.na_rep = na_rep | ||
self.decimal = decimal | ||
self.col_space = col_space | ||
if col_space is None: | ||
self.col_space = {} | ||
elif isinstance(col_space, (int, str)): | ||
self.col_space = {"": col_space} | ||
self.col_space.update({column: col_space for column in self.frame.columns}) | ||
elif isinstance(col_space, dict): | ||
for column in col_space.keys(): | ||
if column not in self.frame.columns and column != "": | ||
raise ValueError( | ||
f"Col_space is defined for an unknown column: {column}" | ||
) | ||
self.col_space = col_space | ||
else: | ||
col_space = cast(Sequence, col_space) | ||
if len(frame.columns) != len(col_space): | ||
raise ValueError( | ||
f"Col_space length({len(col_space)}) should match " | ||
f"DataFrame number of columns({len(frame.columns)})" | ||
) | ||
self.col_space = dict(zip(self.frame.columns, col_space)) | ||
|
||
self.header = header | ||
self.index = index | ||
self.line_width = line_width | ||
|
@@ -702,7 +728,7 @@ def _to_str_columns(self) -> List[List[str]]: | |
""" | ||
# this method is not used by to_html where self.col_space | ||
# could be a string so safe to cast | ||
self.col_space = cast(int, self.col_space) | ||
col_space = {k: cast(int, v) for k, v in self.col_space.items()} | ||
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. Is the cast still required here? 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. @WillAyd Not an actual cast, typing.cast just used to signal to the type checker (mypy). In this case self.col_space can be of type dict<str> by definition but we are sure that it is dict<int> within this scope |
||
|
||
frame = self.tr_frame | ||
# may include levels names also | ||
|
@@ -714,10 +740,7 @@ def _to_str_columns(self) -> List[List[str]]: | |
for i, c in enumerate(frame): | ||
fmt_values = self._format_col(i) | ||
fmt_values = _make_fixed_width( | ||
fmt_values, | ||
self.justify, | ||
minimum=(self.col_space or 0), | ||
adj=self.adj, | ||
fmt_values, self.justify, minimum=col_space.get(c, 0), adj=self.adj, | ||
) | ||
stringified.append(fmt_values) | ||
else: | ||
|
@@ -741,7 +764,7 @@ def _to_str_columns(self) -> List[List[str]]: | |
for i, c in enumerate(frame): | ||
cheader = str_columns[i] | ||
header_colwidth = max( | ||
self.col_space or 0, *(self.adj.len(x) for x in cheader) | ||
col_space.get(c, 0), *(self.adj.len(x) for x in cheader) | ||
) | ||
fmt_values = self._format_col(i) | ||
fmt_values = _make_fixed_width( | ||
|
@@ -932,7 +955,7 @@ def _format_col(self, i: int) -> List[str]: | |
formatter, | ||
float_format=self.float_format, | ||
na_rep=self.na_rep, | ||
space=self.col_space, | ||
space=self.col_space.get(frame.columns[i]), | ||
decimal=self.decimal, | ||
) | ||
|
||
|
@@ -1025,7 +1048,7 @@ def show_col_idx_names(self) -> bool: | |
def _get_formatted_index(self, frame: "DataFrame") -> List[str]: | ||
# Note: this is only used by to_string() and to_latex(), not by | ||
# to_html(). so safe to cast col_space here. | ||
self.col_space = cast(int, self.col_space) | ||
col_space = {k: cast(int, v) for k, v in self.col_space.items()} | ||
quangngd marked this conversation as resolved.
Show resolved
Hide resolved
|
||
index = frame.index | ||
columns = frame.columns | ||
fmt = self._get_formatter("__index__") | ||
|
@@ -1043,7 +1066,7 @@ def _get_formatted_index(self, frame: "DataFrame") -> List[str]: | |
fmt_index = [ | ||
tuple( | ||
_make_fixed_width( | ||
list(x), justify="left", minimum=(self.col_space or 0), adj=self.adj | ||
list(x), justify="left", minimum=col_space.get("", 0), adj=self.adj, | ||
) | ||
) | ||
for x in fmt_index | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor but you can just create the dict inline using a comprehension on one line instead of doing this then calling update on the next
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@WillAyd The
""
(empty) key is for the row id column. Couldn't think of how to turn this into a oneliner?