Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions superset/utils/pandas_postprocessing/boxplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,16 @@ def outliers(series: Series) -> set[float]:
# "mean"/"median" are passed as strings rather than np.mean/np.median: the
# callables trigger a pandas FutureWarning in GroupBy.agg (see
# _PANDAS_STRING_AGGREGATORS in pandas_postprocessing/utils.py) and the
# string form resolves to the exact same aggregation.
# string form resolves to the exact same aggregation. Under MINMAX,
# whisker_high/whisker_low are themselves plain np.max/np.min, so the same
# substitution applies there; under TUKEY/PERCENTILE they're closures and
# aren't eligible for the string shortcut.
is_minmax = whisker_type == PostProcessingBoxplotWhiskerType.MINMAX
operators: dict[str, Union[str, Callable[[Any], Any]]] = {
"mean": "mean",
"median": "median",
"max": whisker_high,
"min": whisker_low,
"max": "max" if is_minmax else whisker_high,
"min": "min" if is_minmax else whisker_low,
"q1": quartile1,
"q3": quartile3,
"count": np.ma.count,
Expand Down
22 changes: 22 additions & 0 deletions tests/unit_tests/pandas_postprocessing/test_boxplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,28 @@ def test_boxplot_mean_median_no_future_warning():
assert series_to_list(df["cars__median"]) == series_to_list(expected["median"])


def test_boxplot_minmax_no_future_warning():
"""Under MINMAX, whisker_high/whisker_low are plain np.max/np.min, which
must be passed as strings (not the callables) to GroupBy.agg, else pandas
raises a FutureWarning. Also verify the values match a plain pandas
groupby, since the string and callable forms could silently diverge on a
future pandas version."""
expected = names_df.groupby("region")["cars"].agg(["max", "min"])

with warnings.catch_warnings():
warnings.simplefilter("error", FutureWarning)
df = boxplot(
df=names_df,
groupby=["region"],
whisker_type=PostProcessingBoxplotWhiskerType.MINMAX,
metrics=["cars"],
)

df = df.set_index("region")
assert series_to_list(df["cars__max"]) == series_to_list(expected["max"])
assert series_to_list(df["cars__min"]) == series_to_list(expected["min"])


def test_boxplot_min_max():
df = boxplot(
df=names_df,
Expand Down
Loading