diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index 735fb345363c7..fa55d163376ee 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,8 +1611,39 @@ 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 + """ + + def f(data: DataFrame, props: str) -> np.ndarray: + return np.where(pd.isna(data).values, props, "") + + return self.apply( + f, axis=None, subset=subset, props=f"background-color: {null_color};" + ) + 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. @@ -1658,10 +1662,19 @@ def highlight_max( ------- self : Styler """ - return self._highlight_handler(subset=subset, color=color, axis=axis, max_=True) + + def f(data: FrameOrSeries, props: str) -> np.ndarray: + return np.where(data == np.nanmax(data.values), props, "") + + return self.apply( + f, axis=axis, subset=subset, props=f"background-color: {color};" + ) 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. @@ -1680,43 +1693,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 + def f(data: FrameOrSeries, props: str) -> np.ndarray: + return np.where(data == np.nanmin(data.values), props, "") - @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 - ) + return self.apply( + f, axis=axis, subset=subset, props=f"background-color: {color};" + ) @classmethod def from_custom_template(cls, searchpath, name):