Skip to content

Commit 3b3b791

Browse files
ihsansecerjreback
authored andcommitted
BUG: Fix empty closed window issue with rolling min and max (#27140)
1 parent 54f4514 commit 3b3b791

File tree

3 files changed

+23
-2
lines changed

3 files changed

+23
-2
lines changed

doc/source/whatsnew/v0.25.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,7 @@ Groupby/resample/rolling
858858
- Bug in :meth:`pandas.core.window.Rolling.median` and :meth:`pandas.core.window.Rolling.quantile` where MemoryError is raised with empty window (:issue:`26005`)
859859
- Bug in :meth:`pandas.core.window.Rolling.median` and :meth:`pandas.core.window.Rolling.quantile` where incorrect results are returned with ``closed='left'`` and ``closed='neither'`` (:issue:`26005`)
860860
- Improved :class:`pandas.core.window.Rolling`, :class:`pandas.core.window.Window` and :class:`pandas.core.window.EWM` functions to exclude nuisance columns from results instead of raising errors and raise a ``DataError`` only if all columns are nuisance (:issue:`12537`)
861+
- Bug in :meth:`pandas.core.window.Rolling.max` and :meth:`pandas.core.window.Rolling.min` where incorrect results are returned with an empty variable window`` (:issue:`26005`)
861862

862863
Reshaping
863864
^^^^^^^^^

pandas/_libs/window.pyx

+4-2
Original file line numberDiff line numberDiff line change
@@ -1313,9 +1313,11 @@ cdef _roll_min_max_variable(ndarray[numeric] values,
13131313

13141314
# if right is open then the first window is empty
13151315
close_offset = 0 if endi[0] > starti[0] else 1
1316+
# first window's size
1317+
curr_win_size = endi[0] - starti[0]
13161318

13171319
for i in range(endi[0], endi[N-1]):
1318-
if not Q.empty():
1320+
if not Q.empty() and curr_win_size > 0:
13191321
output[i-1+close_offset] = calc_mm(
13201322
minp, nobs, values[Q.front()])
13211323
else:
@@ -1344,7 +1346,7 @@ cdef _roll_min_max_variable(ndarray[numeric] values,
13441346
Q.push_back(i)
13451347
W.push_back(i)
13461348

1347-
if not Q.empty():
1349+
if not Q.empty() and curr_win_size > 0:
13481350
output[N-1] = calc_mm(minp, nobs, values[Q.front()])
13491351
else:
13501352
output[N-1] = NaN

pandas/tests/test_window.py

+18
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ def win_types_special(request):
4848
return request.param
4949

5050

51+
@pytest.fixture(params=["sum", "mean", "median", "max", "min",
52+
"var", "std", "kurt", "skew"])
53+
def arithmetic_win_operators(request):
54+
return request.param
55+
56+
5157
class Base:
5258

5359
_nan_locs = np.arange(20, 40)
@@ -522,6 +528,18 @@ def test_closed(self):
522528
with pytest.raises(ValueError):
523529
df.rolling(window=3, closed='neither')
524530

531+
@pytest.mark.parametrize("closed", ["neither", "left"])
532+
def test_closed_empty(self, closed, arithmetic_win_operators):
533+
# GH 26005
534+
func_name = arithmetic_win_operators
535+
ser = pd.Series(data=np.arange(5),
536+
index=pd.date_range("2000", periods=5, freq="2D"))
537+
roll = ser.rolling("1D", closed=closed)
538+
539+
result = getattr(roll, func_name)()
540+
expected = pd.Series([np.nan] * 5, index=ser.index)
541+
tm.assert_series_equal(result, expected)
542+
525543
@pytest.mark.parametrize("func", ['min', 'max'])
526544
def test_closed_one_entry(self, func):
527545
# GH24718

0 commit comments

Comments
 (0)