diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index 7f07187e34c78..cc44f43ba8acf 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -1042,6 +1042,7 @@ Styler - Bug in :meth:`Styler.set_sticky` leading to white text on white background in dark mode (:issue:`46984`) - Bug in :meth:`Styler.to_latex` causing ``UnboundLocalError`` when ``clines="all;data"`` and the ``DataFrame`` has no rows. (:issue:`47203`) - Bug in :meth:`Styler.to_excel` when using ``vertical-align: middle;`` with ``xlsxwriter`` engine (:issue:`30107`) +- Bug when applying styles to a DataFrame with boolean column labels (:issue:`47838`) Metadata ^^^^^^^^ diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index fbee64771cd9a..f19c4d04f059e 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -2977,6 +2977,12 @@ def hide( # A collection of "builtin" styles # ----------------------------------------------------------------------- + def _get_numeric_subset_default(self): + # Returns a boolean mask indicating where `self.data` has numerical columns. + # Choosing a mask as opposed to the column names also works for + # boolean column labels (GH47838). + return self.data.columns.isin(self.data.select_dtypes(include=np.number)) + @doc( name="background", alt="text", @@ -3120,7 +3126,7 @@ def background_gradient( .. figure:: ../../_static/style/{image_prefix}_axNone_gmap.png """ if subset is None and gmap is None: - subset = self.data.select_dtypes(include=np.number).columns + subset = self._get_numeric_subset_default() self.apply( _background_gradient, @@ -3155,7 +3161,7 @@ def text_gradient( gmap: Sequence | None = None, ) -> Styler: if subset is None and gmap is None: - subset = self.data.select_dtypes(include=np.number).columns + subset = self._get_numeric_subset_default() return self.apply( _background_gradient, @@ -3308,7 +3314,7 @@ def bar( raise ValueError(f"`height` must be a value in [0, 100], got {height}") if subset is None: - subset = self.data.select_dtypes(include=np.number).columns + subset = self._get_numeric_subset_default() self.apply( _bar, diff --git a/pandas/tests/io/formats/style/test_style.py b/pandas/tests/io/formats/style/test_style.py index 23b05c8242274..192fec048a930 100644 --- a/pandas/tests/io/formats/style/test_style.py +++ b/pandas/tests/io/formats/style/test_style.py @@ -746,6 +746,22 @@ def color_negative_red(val): df.loc[pct_subset] df.style.applymap(color_negative_red, subset=pct_subset) + @pytest.mark.parametrize( + "stylefunc", ["background_gradient", "bar", "text_gradient"] + ) + def test_subset_for_boolean_cols(self, stylefunc): + # GH47838 + df = DataFrame( + [ + [1, 2], + [3, 4], + ], + columns=[False, True], + ) + styled = getattr(df.style, stylefunc)() + styled._compute() + assert set(styled.ctx) == {(0, 0), (0, 1), (1, 0), (1, 1)} + def test_empty(self): df = DataFrame({"A": [1, 0]}) s = df.style