Skip to content

Commit e7e93e3

Browse files
authored
Backport PR #42861 on branch 1.3.x (#42879)
1 parent 3f11720 commit e7e93e3

File tree

3 files changed

+41
-13
lines changed

3 files changed

+41
-13
lines changed

doc/source/whatsnew/v1.3.2.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Fixed regressions
2222
- Regression in :meth:`DataFrame.drop` does nothing if :class:`MultiIndex` has duplicates and indexer is a tuple or list of tuples (:issue:`42771`)
2323
- Fixed regression where :meth:`pandas.read_csv` raised a ``ValueError`` when parameters ``names`` and ``prefix`` were both set to None (:issue:`42387`)
2424
- Fixed regression in comparisons between :class:`Timestamp` object and ``datetime64`` objects outside the implementation bounds for nanosecond ``datetime64`` (:issue:`42794`)
25-
-
25+
- Fixed regression in :meth:`.Styler.highlight_min` and :meth:`.Styler.highlight_max` where ``pandas.NA`` was not successfully ignored (:issue:`42650`)
2626

2727
.. ---------------------------------------------------------------------------
2828

pandas/io/formats/style.py

+18-8
Original file line numberDiff line numberDiff line change
@@ -2312,15 +2312,15 @@ def highlight_max(
23122312
Styler.highlight_quantile: Highlight values defined by a quantile with a style.
23132313
"""
23142314

2315-
def f(data: FrameOrSeries, props: str) -> np.ndarray:
2316-
return np.where(data == np.nanmax(data.to_numpy()), props, "")
2317-
23182315
if props is None:
23192316
props = f"background-color: {color};"
23202317
# error: Argument 1 to "apply" of "Styler" has incompatible type
23212318
# "Callable[[FrameOrSeries, str], ndarray]"; expected "Callable[..., Styler]"
23222319
return self.apply(
2323-
f, axis=axis, subset=subset, props=props # type: ignore[arg-type]
2320+
partial(_highlight_value, op="max"), # type: ignore[arg-type]
2321+
axis=axis,
2322+
subset=subset,
2323+
props=props,
23242324
)
23252325

23262326
def highlight_min(
@@ -2363,15 +2363,15 @@ def highlight_min(
23632363
Styler.highlight_quantile: Highlight values defined by a quantile with a style.
23642364
"""
23652365

2366-
def f(data: FrameOrSeries, props: str) -> np.ndarray:
2367-
return np.where(data == np.nanmin(data.to_numpy()), props, "")
2368-
23692366
if props is None:
23702367
props = f"background-color: {color};"
23712368
# error: Argument 1 to "apply" of "Styler" has incompatible type
23722369
# "Callable[[FrameOrSeries, str], ndarray]"; expected "Callable[..., Styler]"
23732370
return self.apply(
2374-
f, axis=axis, subset=subset, props=props # type: ignore[arg-type]
2371+
partial(_highlight_value, op="min"), # type: ignore[arg-type]
2372+
axis=axis,
2373+
subset=subset,
2374+
props=props,
23752375
)
23762376

23772377
def highlight_between(
@@ -2870,3 +2870,13 @@ def _highlight_between(
28702870
else np.full(data.shape, True, dtype=bool)
28712871
)
28722872
return np.where(g_left & l_right, props, "")
2873+
2874+
2875+
def _highlight_value(data: FrameOrSeries, op: str, props: str) -> np.ndarray:
2876+
"""
2877+
Return an array of css strings based on the condition of values matching an op.
2878+
"""
2879+
value = getattr(data, op)(skipna=True)
2880+
if isinstance(data, DataFrame): # min/max must be done twice to return scalar
2881+
value = getattr(value, op)(skipna=True)
2882+
return np.where(data == value, props, "")

pandas/tests/io/formats/style/test_highlight.py

+22-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
import pytest
33

44
from pandas import (
5+
NA,
56
DataFrame,
67
IndexSlice,
78
)
8-
import pandas._testing as tm
99

1010
pytest.importorskip("jinja2")
1111

@@ -55,9 +55,7 @@ def test_highlight_minmax_basic(df, f):
5555
}
5656
if f == "highlight_min":
5757
df = -df
58-
with tm.assert_produces_warning(RuntimeWarning):
59-
# All-NaN slice encountered
60-
result = getattr(df.style, f)(axis=1, color="red")._compute().ctx
58+
result = getattr(df.style, f)(axis=1, color="red")._compute().ctx
6159
assert result == expected
6260

6361

@@ -78,6 +76,26 @@ def test_highlight_minmax_ext(df, f, kwargs):
7876
assert result == expected
7977

8078

79+
@pytest.mark.parametrize("f", ["highlight_min", "highlight_max"])
80+
@pytest.mark.parametrize("axis", [None, 0, 1])
81+
def test_highlight_minmax_nulls(f, axis):
82+
# GH 42750
83+
expected = {
84+
(1, 0): [("background-color", "yellow")],
85+
(1, 1): [("background-color", "yellow")],
86+
}
87+
if axis == 1:
88+
expected.update({(2, 1): [("background-color", "yellow")]})
89+
90+
if f == "highlight_max":
91+
df = DataFrame({"a": [NA, 1, None], "b": [np.nan, 1, -1]})
92+
else:
93+
df = DataFrame({"a": [NA, -1, None], "b": [np.nan, -1, 1]})
94+
95+
result = getattr(df.style, f)(axis=axis)._compute().ctx
96+
assert result == expected
97+
98+
8199
@pytest.mark.parametrize(
82100
"kwargs",
83101
[

0 commit comments

Comments
 (0)