diff --git a/asv_bench/benchmarks/rolling.py b/asv_bench/benchmarks/rolling.py index f85dc83ab8605..e3c9c7ccdc51c 100644 --- a/asv_bench/benchmarks/rolling.py +++ b/asv_bench/benchmarks/rolling.py @@ -150,19 +150,18 @@ def time_quantile(self, constructor, window, dtype, percentile, interpolation): self.roll.quantile(percentile, interpolation=interpolation) -class PeakMemFixed: - def setup(self): - N = 10 - arr = 100 * np.random.random(N) - self.roll = pd.Series(arr).rolling(10) - - def peakmem_fixed(self): - # GH 25926 - # This is to detect memory leaks in rolling operations. - # To save time this is only ran on one method. - # 6000 iterations is enough for most types of leaks to be detected - for x in range(6000): - self.roll.max() +class PeakMemFixedWindowMinMax: + + params = ["min", "max"] + + def setup(self, operation): + N = int(1e6) + arr = np.random.random(N) + self.roll = pd.Series(arr).rolling(2) + + def peakmem_fixed(self, operation): + for x in range(5): + getattr(self.roll, operation)() class ForwardWindowMethods: diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index 07849702c646d..43bf0e82490e2 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -608,6 +608,7 @@ Groupby/resample/rolling - Bug in :meth:`DataFrame.resample` where an ``AmbiguousTimeError`` would be raised when the resulting timezone aware :class:`DatetimeIndex` had a DST transition at midnight (:issue:`25758`) - Bug in :meth:`DataFrame.groupby` where a ``ValueError`` would be raised when grouping by a categorical column with read-only categories and ``sort=False`` (:issue:`33410`) - Bug in :meth:`GroupBy.first` and :meth:`GroupBy.last` where None is not preserved in object dtype (:issue:`32800`) +- Bug in :meth:`Rolling.min` and :meth:`Rolling.max`: Growing memory usage after multiple calls when using a fixed window (:issue:`30726`) Reshaping ^^^^^^^^^ diff --git a/pandas/_libs/window/aggregations.pyx b/pandas/_libs/window/aggregations.pyx index 673820fd8464a..afa0539014041 100644 --- a/pandas/_libs/window/aggregations.pyx +++ b/pandas/_libs/window/aggregations.pyx @@ -971,8 +971,8 @@ cdef inline numeric calc_mm(int64_t minp, Py_ssize_t nobs, return result -def roll_max_fixed(ndarray[float64_t] values, ndarray[int64_t] start, - ndarray[int64_t] end, int64_t minp, int64_t win): +def roll_max_fixed(float64_t[:] values, int64_t[:] start, + int64_t[:] end, int64_t minp, int64_t win): """ Moving max of 1d array of any numeric type along axis=0 ignoring NaNs. @@ -988,7 +988,7 @@ def roll_max_fixed(ndarray[float64_t] values, ndarray[int64_t] start, make the interval closed on the right, left, both or neither endpoints """ - return _roll_min_max_fixed(values, start, end, minp, win, is_max=1) + return _roll_min_max_fixed(values, minp, win, is_max=1) def roll_max_variable(ndarray[float64_t] values, ndarray[int64_t] start, @@ -1011,8 +1011,8 @@ def roll_max_variable(ndarray[float64_t] values, ndarray[int64_t] start, return _roll_min_max_variable(values, start, end, minp, is_max=1) -def roll_min_fixed(ndarray[float64_t] values, ndarray[int64_t] start, - ndarray[int64_t] end, int64_t minp, int64_t win): +def roll_min_fixed(float64_t[:] values, int64_t[:] start, + int64_t[:] end, int64_t minp, int64_t win): """ Moving min of 1d array of any numeric type along axis=0 ignoring NaNs. @@ -1025,7 +1025,7 @@ def roll_min_fixed(ndarray[float64_t] values, ndarray[int64_t] start, index : ndarray, optional index for window computation """ - return _roll_min_max_fixed(values, start, end, minp, win, is_max=0) + return _roll_min_max_fixed(values, minp, win, is_max=0) def roll_min_variable(ndarray[float64_t] values, ndarray[int64_t] start, @@ -1112,9 +1112,7 @@ cdef _roll_min_max_variable(ndarray[numeric] values, return output -cdef _roll_min_max_fixed(ndarray[numeric] values, - ndarray[int64_t] starti, - ndarray[int64_t] endi, +cdef _roll_min_max_fixed(numeric[:] values, int64_t minp, int64_t win, bint is_max):