Skip to content

Commit b0870e3

Browse files
AlexKirkoCloseChoice
authored andcommitted
BUG: support count function for custom BaseIndexer rolling windows (pandas-dev#33605)
1 parent f6029b6 commit b0870e3

File tree

4 files changed

+11
-6
lines changed

4 files changed

+11
-6
lines changed

doc/source/whatsnew/v1.1.0.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,8 @@ Other API changes
174174
- Added :meth:`DataFrame.value_counts` (:issue:`5377`)
175175
- :meth:`Groupby.groups` now returns an abbreviated representation when called on large dataframes (:issue:`1135`)
176176
- ``loc`` lookups with an object-dtype :class:`Index` and an integer key will now raise ``KeyError`` instead of ``TypeError`` when key is missing (:issue:`31905`)
177-
- Using a :func:`pandas.api.indexers.BaseIndexer` with ``count``, ``skew``, ``cov``, ``corr`` will now raise a ``NotImplementedError`` (:issue:`32865`)
178-
- Using a :func:`pandas.api.indexers.BaseIndexer` with ``min``, ``max`` will now return correct results for any monotonic :func:`pandas.api.indexers.BaseIndexer` descendant (:issue:`32865`)
177+
- Using a :func:`pandas.api.indexers.BaseIndexer` with ``skew``, ``cov``, ``corr`` will now raise a ``NotImplementedError`` (:issue:`32865`)
178+
- Using a :func:`pandas.api.indexers.BaseIndexer` with ``count``, ``min``, ``max`` will now return correct results for any monotonic :func:`pandas.api.indexers.BaseIndexer` descendant (:issue:`32865`)
179179
- Added a :func:`pandas.api.indexers.FixedForwardWindowIndexer` class to support forward-looking windows during ``rolling`` operations.
180180
-
181181

pandas/core/window/common.py

+1
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ def func(arg, window, min_periods=None):
328328
def validate_baseindexer_support(func_name: Optional[str]) -> None:
329329
# GH 32865: These functions work correctly with a BaseIndexer subclass
330330
BASEINDEXER_WHITELIST = {
331+
"count",
331332
"min",
332333
"max",
333334
"mean",

pandas/core/window/rolling.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -1171,8 +1171,9 @@ class _Rolling_and_Expanding(_Rolling):
11711171
)
11721172

11731173
def count(self):
1174-
if isinstance(self.window, BaseIndexer):
1175-
validate_baseindexer_support("count")
1174+
# GH 32865. Using count with custom BaseIndexer subclass
1175+
# implementations shouldn't end up here
1176+
assert not isinstance(self.window, BaseIndexer)
11761177

11771178
blocks, obj = self._create_blocks()
11781179
results = []
@@ -1939,7 +1940,9 @@ def aggregate(self, func, *args, **kwargs):
19391940
def count(self):
19401941

19411942
# different impl for freq counting
1942-
if self.is_freq_type:
1943+
# GH 32865. Use a custom count function implementation
1944+
# when using a BaseIndexer subclass as a window
1945+
if self.is_freq_type or isinstance(self.window, BaseIndexer):
19431946
window_func = self._get_roll_func("roll_count")
19441947
return self._apply(window_func, center=self.center, name="count")
19451948

pandas/tests/window/test_base_indexer.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def get_window_bounds(self, num_values, min_periods, center, closed):
8282
df.rolling(indexer, win_type="boxcar")
8383

8484

85-
@pytest.mark.parametrize("func", ["count", "skew", "cov", "corr"])
85+
@pytest.mark.parametrize("func", ["skew", "cov", "corr"])
8686
def test_notimplemented_functions(func):
8787
# GH 32865
8888
class CustomIndexer(BaseIndexer):
@@ -99,6 +99,7 @@ def get_window_bounds(self, num_values, min_periods, center, closed):
9999
@pytest.mark.parametrize(
100100
"func,np_func,expected,np_kwargs",
101101
[
102+
("count", len, [3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 2.0, np.nan], {},),
102103
("min", np.min, [0.0, 1.0, 2.0, 3.0, 4.0, 6.0, 6.0, 7.0, 8.0, np.nan], {},),
103104
(
104105
"max",

0 commit comments

Comments
 (0)