Skip to content

Commit cb71376

Browse files
authored
BUG: support skew function for custom BaseIndexer rolling windows (#33745)
1 parent e008a0a commit cb71376

File tree

5 files changed

+42
-11
lines changed

5 files changed

+42
-11
lines changed

doc/source/user_guide/computation.rst

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,8 @@ We provide a number of common statistical functions:
318318
:meth:`~Rolling.kurt`, Sample kurtosis (4th moment)
319319
:meth:`~Rolling.quantile`, Sample quantile (value at %)
320320
:meth:`~Rolling.apply`, Generic apply
321-
:meth:`~Rolling.cov`, Unbiased covariance (binary)
322-
:meth:`~Rolling.corr`, Correlation (binary)
321+
:meth:`~Rolling.cov`, Sample covariance (binary)
322+
:meth:`~Rolling.corr`, Sample correlation (binary)
323323

324324
.. _computation.window_variance.caveats:
325325

@@ -341,6 +341,8 @@ We provide a number of common statistical functions:
341341
sample variance under the circumstances would result in a biased estimator
342342
of the variable we are trying to determine.
343343

344+
The same caveats apply to using any supported statistical sample methods.
345+
344346
.. _stats.rolling_apply:
345347

346348
Rolling apply
@@ -870,12 +872,12 @@ Method summary
870872
:meth:`~Expanding.max`, Maximum
871873
:meth:`~Expanding.std`, Sample standard deviation
872874
:meth:`~Expanding.var`, Sample variance
873-
:meth:`~Expanding.skew`, Unbiased skewness (3rd moment)
874-
:meth:`~Expanding.kurt`, Unbiased kurtosis (4th moment)
875+
:meth:`~Expanding.skew`, Sample skewness (3rd moment)
876+
:meth:`~Expanding.kurt`, Sample kurtosis (4th moment)
875877
:meth:`~Expanding.quantile`, Sample quantile (value at %)
876878
:meth:`~Expanding.apply`, Generic apply
877-
:meth:`~Expanding.cov`, Unbiased covariance (binary)
878-
:meth:`~Expanding.corr`, Correlation (binary)
879+
:meth:`~Expanding.cov`, Sample covariance (binary)
880+
:meth:`~Expanding.corr`, Sample correlation (binary)
879881

880882
.. note::
881883

@@ -884,6 +886,8 @@ Method summary
884886
windows. See :ref:`this section <computation.window_variance.caveats>` for more
885887
information.
886888

889+
The same caveats apply to using any supported statistical sample methods.
890+
887891
.. currentmodule:: pandas
888892

889893
Aside from not having a ``window`` parameter, these functions have the same

doc/source/whatsnew/v1.1.0.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,8 @@ Other API changes
175175
- Added :meth:`DataFrame.value_counts` (:issue:`5377`)
176176
- :meth:`Groupby.groups` now returns an abbreviated representation when called on large dataframes (:issue:`1135`)
177177
- ``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`)
178-
- Using a :func:`pandas.api.indexers.BaseIndexer` with ``skew``, ``cov``, ``corr`` will now raise a ``NotImplementedError`` (:issue:`32865`)
179-
- Using a :func:`pandas.api.indexers.BaseIndexer` with ``count``, ``min``, ``max``, ``median`` will now return correct results for any monotonic :func:`pandas.api.indexers.BaseIndexer` descendant (:issue:`32865`)
178+
- Using a :func:`pandas.api.indexers.BaseIndexer` with ``cov``, ``corr`` will now raise a ``NotImplementedError`` (:issue:`32865`)
179+
- Using a :func:`pandas.api.indexers.BaseIndexer` with ``count``, ``min``, ``max``, ``median``, ``skew`` will now return correct results for any monotonic :func:`pandas.api.indexers.BaseIndexer` descendant (:issue:`32865`)
180180
- Added a :func:`pandas.api.indexers.FixedForwardWindowIndexer` class to support forward-looking windows during ``rolling`` operations.
181181
-
182182

pandas/core/window/common.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ def validate_baseindexer_support(func_name: Optional[str]) -> None:
337337
"median",
338338
"std",
339339
"var",
340+
"skew",
340341
"kurt",
341342
"quantile",
342343
}

pandas/core/window/rolling.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -472,13 +472,13 @@ def _apply(
472472

473473
def calc(x):
474474
x = np.concatenate((x, additional_nans))
475-
if not isinstance(window, BaseIndexer):
475+
if not isinstance(self.window, BaseIndexer):
476476
min_periods = calculate_min_periods(
477477
window, self.min_periods, len(x), require_min_periods, floor
478478
)
479479
else:
480480
min_periods = calculate_min_periods(
481-
self.min_periods or 1,
481+
window_indexer.window_size,
482482
self.min_periods,
483483
len(x),
484484
require_min_periods,

pandas/tests/window/test_base_indexer.py

Lines changed: 27 additions & 1 deletion
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", ["skew", "cov", "corr"])
85+
@pytest.mark.parametrize("func", ["cov", "corr"])
8686
def test_notimplemented_functions(func):
8787
# GH 32865
8888
class CustomIndexer(BaseIndexer):
@@ -184,3 +184,29 @@ def test_rolling_forward_window(constructor, func, np_func, expected, np_kwargs)
184184
result3 = getattr(rolling3, func)()
185185
expected3 = constructor(rolling3.apply(lambda x: np_func(x, **np_kwargs)))
186186
tm.assert_equal(result3, expected3)
187+
188+
189+
@pytest.mark.parametrize("constructor", [Series, DataFrame])
190+
def test_rolling_forward_skewness(constructor):
191+
values = np.arange(10)
192+
values[5] = 100.0
193+
194+
indexer = FixedForwardWindowIndexer(window_size=5)
195+
rolling = constructor(values).rolling(window=indexer, min_periods=3)
196+
result = rolling.skew()
197+
198+
expected = constructor(
199+
[
200+
0.0,
201+
2.232396,
202+
2.229508,
203+
2.228340,
204+
2.229091,
205+
2.231989,
206+
0.0,
207+
0.0,
208+
np.nan,
209+
np.nan,
210+
]
211+
)
212+
tm.assert_equal(result, expected)

0 commit comments

Comments
 (0)