From 10d01ca8735ac4f45258cc9df57b0de6ae08068f Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Sat, 13 Feb 2021 17:21:59 +0100 Subject: [PATCH 1/4] CLN: compact styler builtins after `axis=none` allows ndarray --- pandas/io/formats/style.py | 125 ++++++++++++++++++------------------- 1 file changed, 61 insertions(+), 64 deletions(-) diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index 735fb345363c7..22fd1ed756b95 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -1296,33 +1296,6 @@ def hide_columns(self, subset) -> Styler: # A collection of "builtin" styles # ----------------------------------------------------------------------- - @staticmethod - def _highlight_null(v, null_color: str) -> str: - return f"background-color: {null_color}" if pd.isna(v) else "" - - def highlight_null( - self, - null_color: str = "red", - subset: Optional[IndexLabel] = None, - ) -> Styler: - """ - Shade the background ``null_color`` for missing values. - - Parameters - ---------- - null_color : str, default 'red' - subset : label or list of labels, default None - A valid slice for ``data`` to limit the style application to. - - .. versionadded:: 1.1.0 - - Returns - ------- - self : Styler - """ - self.applymap(self._highlight_null, null_color=null_color, subset=subset) - return self - def background_gradient( self, cmap="PuBu", @@ -1638,6 +1611,34 @@ def bar( return self + def highlight_null( + self, + null_color: str = "red", + subset: Optional[IndexLabel] = None, + ) -> Styler: + """ + Shade the background ``null_color`` for missing values. + + Parameters + ---------- + null_color : str, default 'red' + subset : label or list of labels, default None + A valid slice for ``data`` to limit the style application to. + + .. versionadded:: 1.1.0 + + Returns + ------- + self : Styler + """ + return self.apply( + _Builtins._highlight_func, + axis=None, + subset=subset, + props=f"background-color: {null_color};", + highlight="null", + ) + def highlight_max( self, subset=None, color: str = "yellow", axis: Optional[Axis] = 0 ) -> Styler: @@ -1658,7 +1659,13 @@ def highlight_max( ------- self : Styler """ - return self._highlight_handler(subset=subset, color=color, axis=axis, max_=True) + return self.apply( + _Builtins._highlight_func, + axis=axis, + subset=subset, + props=f"background-color: {color};", + highlight="max", + ) def highlight_min( self, subset=None, color: str = "yellow", axis: Optional[Axis] = 0 @@ -1680,43 +1687,13 @@ def highlight_min( ------- self : Styler """ - return self._highlight_handler( - subset=subset, color=color, axis=axis, max_=False - ) - - def _highlight_handler( - self, - subset=None, - color: str = "yellow", - axis: Optional[Axis] = None, - max_: bool = True, - ) -> Styler: - subset = non_reducing_slice(maybe_numeric_slice(self.data, subset)) - self.apply( - self._highlight_extrema, color=color, axis=axis, subset=subset, max_=max_ + return self.apply( + _Builtins._highlight_func, + axis=axis, + subset=subset, + props=f"background-color: {color};", + highlight="min", ) - return self - - @staticmethod - def _highlight_extrema( - data: FrameOrSeries, color: str = "yellow", max_: bool = True - ): - """ - Highlight the min or max in a Series or DataFrame. - """ - attr = f"background-color: {color}" - - if max_: - extrema = data == np.nanmax(data.to_numpy()) - else: - extrema = data == np.nanmin(data.to_numpy()) - - if data.ndim == 1: # Series from .apply - return [attr if v else "" for v in extrema] - else: # DataFrame from .tee - return pd.DataFrame( - np.where(extrema, attr, ""), index=data.index, columns=data.columns - ) @classmethod def from_custom_template(cls, searchpath, name): @@ -1820,6 +1797,26 @@ def pipe(self, func: Callable, *args, **kwargs): return com.pipe(self, func, *args, **kwargs) +class _Builtins: + @staticmethod + def _highlight_func( + data: FrameOrSeries, + props: str = "background-color: yellow;", + highlight: str = "max", + ): + """ + Highlight the value in a Series or DataFrame by func with css-properties + """ + if highlight == "max": + return np.where(data == np.nanmax(data.values), props, "") + elif highlight == "min": + return np.where(data == np.nanmin(data.values), props, "") + elif highlight == "null": + return np.where(pd.isna(data).values, props, "") + else: + raise ValueError("'highlight' must one of 'max', 'min', 'null'") + + class _Tooltips: """ An extension to ``Styler`` that allows for and manipulates tooltips on hover From 45fb229826ace0e5b742d2cff655fd0845e8c85c Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Sat, 13 Feb 2021 19:18:13 +0100 Subject: [PATCH 2/4] BUG: col class identifiers missing from one row --- pandas/io/formats/style.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index 22fd1ed756b95..de522015945c0 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -1640,7 +1640,10 @@ def highlight_null( ) def highlight_max( - self, subset=None, color: str = "yellow", axis: Optional[Axis] = 0 + self, + subset: Optional[IndexLabel] = None, + color: str = "yellow", + axis: Optional[Axis] = 0, ) -> Styler: """ Highlight the maximum by shading the background. @@ -1668,7 +1671,10 @@ def highlight_max( ) def highlight_min( - self, subset=None, color: str = "yellow", axis: Optional[Axis] = 0 + self, + subset: Optional[IndexLabel] = None, + color: str = "yellow", + axis: Optional[Axis] = 0, ) -> Styler: """ Highlight the minimum by shading the background. @@ -1803,7 +1809,7 @@ def _highlight_func( data: FrameOrSeries, props: str = "background-color: yellow;", highlight: str = "max", - ): + ) -> np.ndarray: """ Highlight the value in a Series or DataFrame by func with css-properties """ From 59baa71a00e86eb86ef8149d201f6b0e9e82ce34 Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Sat, 13 Feb 2021 19:36:56 +0100 Subject: [PATCH 3/4] add kwargs for future --- pandas/io/formats/style.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index de522015945c0..50149ee359bd7 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -1809,6 +1809,7 @@ def _highlight_func( data: FrameOrSeries, props: str = "background-color: yellow;", highlight: str = "max", + **kwargs, ) -> np.ndarray: """ Highlight the value in a Series or DataFrame by func with css-properties From 4fdaaed88a7f30ed4f92bee924be7a633b67789f Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Tue, 16 Feb 2021 10:38:33 +0100 Subject: [PATCH 4/4] req changes --- pandas/io/formats/style.py | 51 +++++++++++--------------------------- 1 file changed, 15 insertions(+), 36 deletions(-) diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index 50149ee359bd7..fa55d163376ee 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -1631,12 +1631,12 @@ def highlight_null( ------- self : Styler """ + + def f(data: DataFrame, props: str) -> np.ndarray: + return np.where(pd.isna(data).values, props, "") + return self.apply( - _Builtins._highlight_func, - axis=None, - subset=subset, - props=f"background-color: {null_color};", - highlight="null", + f, axis=None, subset=subset, props=f"background-color: {null_color};" ) def highlight_max( @@ -1662,12 +1662,12 @@ def highlight_max( ------- self : Styler """ + + def f(data: FrameOrSeries, props: str) -> np.ndarray: + return np.where(data == np.nanmax(data.values), props, "") + return self.apply( - _Builtins._highlight_func, - axis=axis, - subset=subset, - props=f"background-color: {color};", - highlight="max", + f, axis=axis, subset=subset, props=f"background-color: {color};" ) def highlight_min( @@ -1693,12 +1693,12 @@ def highlight_min( ------- self : Styler """ + + def f(data: FrameOrSeries, props: str) -> np.ndarray: + return np.where(data == np.nanmin(data.values), props, "") + return self.apply( - _Builtins._highlight_func, - axis=axis, - subset=subset, - props=f"background-color: {color};", - highlight="min", + f, axis=axis, subset=subset, props=f"background-color: {color};" ) @classmethod @@ -1803,27 +1803,6 @@ def pipe(self, func: Callable, *args, **kwargs): return com.pipe(self, func, *args, **kwargs) -class _Builtins: - @staticmethod - def _highlight_func( - data: FrameOrSeries, - props: str = "background-color: yellow;", - highlight: str = "max", - **kwargs, - ) -> np.ndarray: - """ - Highlight the value in a Series or DataFrame by func with css-properties - """ - if highlight == "max": - return np.where(data == np.nanmax(data.values), props, "") - elif highlight == "min": - return np.where(data == np.nanmin(data.values), props, "") - elif highlight == "null": - return np.where(pd.isna(data).values, props, "") - else: - raise ValueError("'highlight' must one of 'max', 'min', 'null'") - - class _Tooltips: """ An extension to ``Styler`` that allows for and manipulates tooltips on hover