# \[ANN\] RollingWindowArrays.jl - flexible and efficient rolling window operations

**URL:** <https://discourse.julialang.org/t/ann-rollingwindowarrays-jl-flexible-and-efficient-rolling-window-operations/122682>\
**Category:** Package Announcements\
**Tags:** arrays, views\
**Created:** [November 15, 2024, 2:48pm UTC](https://discourse.julialang.org/t/ann-rollingwindowarrays-jl-flexible-and-efficient-rolling-window-operations/122682 "2024-11-15T14:48:35Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [November 15, 2024, 2:48pm UTC](https://discourse.julialang.org/t/ann-rollingwindowarrays-jl-flexible-and-efficient-rolling-window-operations/122682/1 "2024-11-15T14:48:35Z")

</div>

Wanted to announce RollingWindowArrays.jl, a small package I have been working on for rolling winow operations on arrays, in case anyone finds it useful:

```julia-repl
julia> x = rand(6)
6-element Vector{Float64}:
 0.20267030347757775
 0.9461987020973889
 0.19249855800780524
 0.5748456080526526
 0.7032664181878268
 0.6079588708103658

julia> rolling(x, 3)
4-element RollingWindowArrays.RollingWindowVector{SubArray{Float64, 1, Vector{Float64}, Tuple{UnitRange{Int64}}, true}, 1, Vector{Float64}, Nothing}:
 [0.20267030347757775, 0.9461987020973889, 0.19249855800780524]
 [0.9461987020973889, 0.19249855800780524, 0.5748456080526526]
 [0.19249855800780524, 0.5748456080526526, 0.7032664181878268]
 [0.5748456080526526, 0.7032664181878268, 0.6079588708103658]

```

Contrary to RollingFunctions.jl, `rolling` does not take a function argument but instead returns a `RollingWindowVector` that’s simply an `AbstractVector` of views into the original array. Reductions – e.g. a rolling mean – can then be applied simply via broadcasting:

```julia-repl
julia> using Statistics

julia> mean.(rolling(x, 3))
4-element Vector{Float64}:
 0.4471225211942573
 0.5711809560526157
 0.4902035280827615
 0.6286902990169484

```

This allows one to take full advantage of Julia’s higher-level array abstractions, so something like the following “just works” without having to allocate any temporary arrays:

```julia-repl
julia> maximum(mean, rolling(x, 3))
0.6286902990169484

```

This approach also turns out to be quite efficient:

```julia-repl
julia> @b mean.(RollingWindowArrays.rolling($(rand(1000)), 11))
11.953 μs (3 allocs: 7.812 KiB)

julia> @b RollingFunctions.rollmean($rand(1000), 11)
29.676 μs (1491 allocs: 39.406 KiB, <0.01% compile time)

```

What is still missing compared to RollingFunctions.jl is the ability to have tapering or filled windows at the end points as I have not had a use for it yet.

Additional features include the ability to roll over multidimensional arrays and native support for `DimArray`s from DimensionalData.jl. For additional examples, check out the [README](https://github.com/simeonschaub/RollingWindowArrays.jl) .

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [November 15, 2024, 3:39pm UTC](https://discourse.julialang.org/t/ann-rollingwindowarrays-jl-flexible-and-efficient-rolling-window-operations/122682/2 "2024-11-15T15:39:53Z")

</div>

> [@simeonschaub](#):
>
> This approach also turns out to be quite efficient:

Afaiu, it does use the `O(n*k)` naive algorithm for rolling mean, though, instead of the O(n) algorithm. Can you explicitly warn about that? `O(n*k)` is not what most people normally think of when they hear “rolling mean” / “rolling hash”!

Often the entire point is that you can shift the window in O(1) instead of O(k). (k is the window size)

And I would not be very surprised if someone pointed out a very cool paper with a fancy complicated non-obvious algorithm + runtime analysis to compute rolling min / max / median in expected O(n) or O(n log k) or something.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [November 15, 2024, 5:28pm UTC](https://discourse.julialang.org/t/ann-rollingwindowarrays-jl-flexible-and-efficient-rolling-window-operations/122682/3 "2024-11-15T17:28:21Z")

</div>

The underlying algorithm in FastRunningMedian.jl should scale as O(n log k).

---

<div class="post-metadata">

**Author:** ![sairus7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sairus7/32/10816_2.png) [@sairus7](https://discourse.julialang.org/u/sairus7)\
**Post date:** [December 24, 2024, 9:59pm UTC](https://discourse.julialang.org/t/ann-rollingwindowarrays-jl-flexible-and-efficient-rolling-window-operations/122682/4 "2024-12-24T21:59:08Z")

</div>

What about stepping windows (e.g. overlapped by 50%)?

---

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [December 25, 2024, 4:08pm UTC](https://discourse.julialang.org/t/ann-rollingwindowarrays-jl-flexible-and-efficient-rolling-window-operations/122682/5 "2024-12-25T16:08:59Z")

</div>

[GitHub - jw3126/ReduceWindows.jl: Apply reduce over sliding windows](https://github.com/jw3126/ReduceWindows.jl) can do rolling window for associative operations like max in O(N)
