Repository: pandas-dev/pandas
Pull request: BUG: `RollingGroupBy.quantile` ignores `interpolation` keyword argument
- [X] closes #28779
- [X] tests added / passed
- [X] passes `black pandas`
- [X] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [X] whatsnew entry


Problem statement:
`RollingGroupBy.quantile` ignores `interpolation` argument
#### Code Sample, a copy-pastable example if possible

```python
df = pd.DataFrame([
    ['a', 1], ['a', 2], ['a', 3],
    ['b', 1], ['b', 3], ['b', 5]
], columns=['key', 'val'])
print(df.groupby('key').rolling(2).quantile(.4, interpolation='lower'))
```
#### Problem description

The keyword argument `interpolation` is ignored - no matter what value it is set to, the default (linear) interpolation is used.  This problem only applies to `RollingGroupBy.quantile` - `GroupBy.quantile` and `Rolling.quantile` both appear to work as expected.

#### Expected Output

```
       val
key       
a   0  NaN
    1  1.0
    2  2.0
b   3  NaN
    4  1.0
    5  3.0
```

#### Output of ``pd.show_versions()``

INSTALLED VERSIONS
------------------
commit           : None
python           : 3.7.4.final.0
python-bits      : 64
OS               : Darwin
OS-release       : 17.7.0
machine          : x86_64
processor        : i386
byteorder        : little
LC_ALL           : None
LANG             : en_US.UTF-8
LOCALE           : en_US.UTF-8

pandas           : 0.25.1
numpy            : 1.17.2
pytz             : 2019.2
dateutil         : 2.8.0
pip              : 19.2.3
setuptools       : 41.2.0
Cython           : None
pytest           : None
hypothesis       : None
sphinx           : None
blosc            : None
feather          : None
xlsxwriter       : None
lxml.etree       : None
html5lib         : None
pymysql          : None
psycopg2         : None
jinja2           : 2.10.1
IPython          : 7.8.0
pandas_datareader: None
bs4              : None
bottleneck       : None
fastparquet      : None
gcsfs            : None
lxml.etree       : None
matplotlib       : None
numexpr          : None
odfpy            : None
openpyxl         : None
pandas_gbq       : None
pyarrow          : None
pytables         : None
s3fs             : None
scipy            : None
sqlalchemy       : None
tables           : None
xarray           : None
xlrd             : None
xlwt             : None
xlsxwriter       : None

Hints from issue discussion:

Commit message: BUG: `RollingGroupBy.quantile` ignores `interpolation` keyword argument (#28779)

Patch to review:
diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst
index cd012fe755337..3436270ac1bc5 100644
--- a/doc/source/whatsnew/v1.0.0.rst
+++ b/doc/source/whatsnew/v1.0.0.rst
@@ -427,6 +427,7 @@ Groupby/resample/rolling
 - Bug in :meth:`DataFrame.groupby` not offering selection by column name when ``axis=1`` (:issue:`27614`)
 - Bug in :meth:`DataFrameGroupby.agg` not able to use lambda function with named aggregation (:issue:`27519`)
 - Bug in :meth:`DataFrame.groupby` losing column name information when grouping by a categorical column (:issue:`28787`)
+- Bug in :meth:`RollingGroupby.quantile` ignoring ``interpolation`` keyword argument (:issue:`28779`)
 
 Reshaping
 ^^^^^^^^^
diff --git a/pandas/core/window/rolling.py b/pandas/core/window/rolling.py
index caf2f9e1c9dd3..de550132a9f6d 100644
--- a/pandas/core/window/rolling.py
+++ b/pandas/core/window/rolling.py
@@ -1499,7 +1499,9 @@ def f(arg, *args, **kwargs):
                     interpolation,
                 )
 
-        return self._apply(f, "quantile", quantile=quantile, **kwargs)
+        return self._apply(
+            f, "quantile", quantile=quantile, interpolation=interpolation, **kwargs
+        )
 
     _shared_docs[
         "cov"
diff --git a/pandas/tests/window/test_grouper.py b/pandas/tests/window/test_grouper.py
index b726bd3e3c8a7..9c9dbf11bcef8 100644
--- a/pandas/tests/window/test_grouper.py
+++ b/pandas/tests/window/test_grouper.py
@@ -59,7 +59,6 @@ def test_rolling(self):
         r = g.rolling(window=4)
 
         for f in ["sum", "mean", "min", "max", "count", "kurt", "skew"]:
-
             result = getattr(r, f)()
             expected = g.apply(lambda x: getattr(x.rolling(4), f)())
             tm.assert_frame_equal(result, expected)
@@ -69,9 +68,10 @@ def test_rolling(self):
             expected = g.apply(lambda x: getattr(x.rolling(4), f)(ddof=1))
             tm.assert_frame_equal(result, expected)
 
-        result = r.quantile(0.5)
-        expected = g.apply(lambda x: x.rolling(4).quantile(0.5))
-        tm.assert_frame_equal(result, expected)
+        for f in ["linear", "lower", "higher", "midpoint", "nearest"]:
+            result = r.quantile(0.4, interpolation=f)
+            expected = g.apply(lambda x: x.rolling(4).quantile(0.4, interpolation=f))
+            tm.assert_frame_equal(result, expected)
 
     def test_rolling_corr_cov(self):
         g = self.frame.groupby("A")
@@ -141,9 +141,10 @@ def test_expanding(self):
             expected = g.apply(lambda x: getattr(x.expanding(), f)(ddof=0))
             tm.assert_frame_equal(result, expected)
 
-        result = r.quantile(0.5)
-        expected = g.apply(lambda x: x.expanding().quantile(0.5))
-        tm.assert_frame_equal(result, expected)
+        for f in ["linear", "lower", "higher", "midpoint", "nearest"]:
+            result = r.quantile(0.4, interpolation=f)
+            expected = g.apply(lambda x: x.expanding().quantile(0.4, interpolation=f))
+            tm.assert_frame_equal(result, expected)
 
     def test_expanding_corr_cov(self):
         g = self.frame.groupby("A")


Code review comments:
diff_hunk: @@ -69,9 +68,10 @@ def test_rolling(self):
             expected = g.apply(lambda x: getattr(x.rolling(4), f)(ddof=1))
             tm.assert_frame_equal(result, expected)
 
-        result = r.quantile(0.5)
-        expected = g.apply(lambda x: x.rolling(4).quantile(0.5))
-        tm.assert_frame_equal(result, expected)
+        for f in ["linear", "lower", "higher", "midpoint", "nearest"]:
path: pandas/tests/window/test_grouper.py
text: @user1:
Either here or in a follow up could you parametrize this test with these values rather than the loop within? 

@user2:
can  u make this a separate test and parmetrize

@author:
Yes, I think I can handle that here - working on it now.

@author:
I wrote a new test called `test_rolling_quantile` and parametrized the `interpolation` argument as requested, but unfortunately it looks as though most of the tests in this file have broken since I merged in master.  To test, I checked out the upstream master branch, rebuilt my conda environment from scratch, and ran the tests there.  10 of the tests failed, including `test_rolling` (stack trace below).  Is this a known issue?

```
self = <pandas.tests.window.test_grouper.TestGrouperGrouping object at 0x116432208>

    def test_rolling(self):
        g = self.frame.groupby("A")
        r = g.rolling(window=4)

        for f in ["sum", "mean", "min", "max", "count", "kurt", "skew"]:

>           result = getattr(r, f)()

test_grouper.py:64:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../core/window/rolling.py:1870: in sum
    return super().sum(*args, **kwargs)
../../core/window/rolling.py:1245: in sum
    return self._apply("roll_sum", "sum", **kwargs)
../../core/window/common.py:81: in _apply
    return self._groupby.apply(f)
../../core/groupby/groupby.py:718: in apply
    result = self._python_apply_general(f)
../../core/groupby/groupby.py:734: in _python_apply_general
    keys, values, mutated = self.grouper.apply(f, self._selected_obj, self.axis)
../../core/groupby/ops.py:171: in apply
    result_values, mutated = splitter.fast_apply(f, group_keys)
../../core/groupby/ops.py:904: in fast_apply
    return libreduction.apply_frame_axis0(sdata, f, names, starts, ends)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

>   ???
E   AttributeError: 'Int64Index' object has no attribute '_has_complex_internals'

pandas/_libs/reduction.pyx:519: AttributeError
```

@author:
Oops, @user1's suggestion to rebuild the Cython extensions was correct.  The tests are now passing; I'm going to push my changes shortly.

@author:
The change is pushed - let me know if that's different from what you had in mind!