From cf73797985d23960f970c223b096ae52e856033e Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Thu, 8 Aug 2019 14:48:14 -0500 Subject: [PATCH 1/2] BUG: Fix groupby quantile segfault Validate that q is between 0 and 1. Closes #27470 --- doc/source/whatsnew/v0.25.1.rst | 2 +- pandas/_libs/groupby.pyx | 5 +++++ pandas/tests/groupby/test_function.py | 11 +++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.25.1.rst b/doc/source/whatsnew/v0.25.1.rst index f1d3f152e503d..935c094ffae2a 100644 --- a/doc/source/whatsnew/v0.25.1.rst +++ b/doc/source/whatsnew/v0.25.1.rst @@ -119,7 +119,7 @@ Groupby/resample/rolling - Bug in :meth:`pandas.core.groupby.DataFrameGroupBy.transform` where applying a timezone conversion lambda function would drop timezone information (:issue:`27496`) - Bug in windowing over read-only arrays (:issue:`27766`) -- +- Fixed segfault in `pandas.core.groupby.DataFrameGroupBy.quantile` when an invalid quantile was passed (:issue:`27470`) - Reshaping diff --git a/pandas/_libs/groupby.pyx b/pandas/_libs/groupby.pyx index e3f18572abca1..e9cab9133ff4b 100644 --- a/pandas/_libs/groupby.pyx +++ b/pandas/_libs/groupby.pyx @@ -719,6 +719,11 @@ def group_quantile(ndarray[float64_t] out, ndarray[int64_t] counts, non_na_counts, sort_arr assert values.shape[0] == N + + if q < 0 or q > 1: + raise ValueError("'q' must be between 0 and 1. Got" + " '{}' instead".format(q)) + inter_methods = { 'linear': INTERPOLATION_LINEAR, 'lower': INTERPOLATION_LOWER, diff --git a/pandas/tests/groupby/test_function.py b/pandas/tests/groupby/test_function.py index efc3142b25b82..3794120281e1f 100644 --- a/pandas/tests/groupby/test_function.py +++ b/pandas/tests/groupby/test_function.py @@ -1247,6 +1247,17 @@ def test_quantile_raises(): df.groupby("key").quantile() +def test_quantile_out_of_bounds_q_raises(): + # https://github.com/pandas-dev/pandas/issues/27470 + df = pd.DataFrame(dict(a=[0, 0, 0, 1, 1, 1], b=range(6))) + g = df.groupby([0, 0, 0, 1, 1, 1]) + with pytest.raises(ValueError, match="Got '50.0' instead"): + g.quantile(50) + + with pytest.raises(ValueError, match="Got '-1.0' instead"): + g.quantile(-1) + + # pipe # -------------------------------- From 357112277057fc68d670bca354b900f81121e322 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Thu, 8 Aug 2019 15:03:08 -0500 Subject: [PATCH 2/2] prettier --- pandas/_libs/groupby.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/_libs/groupby.pyx b/pandas/_libs/groupby.pyx index e9cab9133ff4b..3069bbbf34bb7 100644 --- a/pandas/_libs/groupby.pyx +++ b/pandas/_libs/groupby.pyx @@ -720,7 +720,7 @@ def group_quantile(ndarray[float64_t] out, assert values.shape[0] == N - if q < 0 or q > 1: + if not (0 <= q <= 1): raise ValueError("'q' must be between 0 and 1. Got" " '{}' instead".format(q))