Skip to content

Commit 0f6bb40

Browse files
committed
add 2side movmean
1 parent 30bc06f commit 0f6bb40

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

src/ArrayStats/ArrayStats.jl

+48
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,54 @@
518518
end
519519
return m
520520
end
521+
522+
523+
"""
524+
movmean(x::AbstractVector{T}, win::Tuple{Int64, Int64}=(1, 1); skip_centre=false) where {T<:Real}
525+
526+
Compute the simple moving average of a 1-dimensional array `x` over a window defined by `win`, returning an array of the same size as `x`.
527+
528+
# Arguments
529+
- `x::AbstractVector{T}`: Input array of type `T`.
530+
- `win::Tuple{Int64, Int64}`: Tuple defining the window size to the left and right of each element. Default is `(1, 1)`.
531+
- `skip_centre::Bool`: If `true`, the center element is skipped in the average calculation. Default is `false`.
532+
533+
# Returns
534+
- `Vector`: An array of the same size as `x` containing the moving averages.
535+
536+
# Example
537+
```julia
538+
x = [1, 2, 3, 4, 5]
539+
win = (1, 1)
540+
movmean(x, win) # returns [1.5, 2.0, 3.0, 4.0, 4.5]
541+
```
542+
"""
543+
function movmean(x::AbstractVector{T}, win::Tuple{Int, Int}=(1, 1);
544+
skip_centre=false) where {T<:Real}
545+
win_left, win_right = win
546+
547+
FT = Base.promote_op(/, T, Int64)
548+
z = similar(x, FT)
549+
== FT(0)
550+
∑w = ∅w = 0
551+
552+
@inbounds @simd for i eachindex(x)
553+
ibeg = max(i - win_left, firstindex(x))
554+
iend = min(i + win_right, lastindex(x))
555+
=
556+
∑w = ∅w
557+
for j = ibeg:iend
558+
skip = skip_centre && i==j
559+
xᵢ = x[j]
560+
notnan = (xᵢ == xᵢ) && !skip
561+
+= ifelse(notnan, xᵢ, ∅)
562+
∑w += ifelse(notnan, 1, 0)
563+
end
564+
z[i] =/ ∑w
565+
end
566+
z
567+
end
568+
521569
function movmean(x::AbstractMatrix{T}, n::Number) where T
522570
mean_type = Base.promote_op(/, T, Int64)
523571
m = Array{mean_type}(undef, size(x))

test/testArrayStats.jl

+6
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,12 @@
485485
# Moving average: 1D
486486
@test movmean(collect(1:10.),5) == movmean(1:10,5)
487487
@test movmean(1:10,5) == [2.0, 2.5, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 8.5, 9.0]
488+
489+
# Moving average: 1D, 2side windows
490+
@test movmean(1:10, (1, 1)) == [1.5, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 9.5]
491+
@test movmean(1:10, (1, 1); skip_centre=true) == [2.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 9.0]
492+
@test movmean(1:10, (1, 2)) == [2.0, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.0, 9.5]
493+
488494
# Moving average: 2D
489495
@test movmean(repeat(1:10,1,10),5) == repeat([2.0, 2.5, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 8.5, 9.0],1,10)
490496
@test movmean(repeat(1:10,1,10)',5) == repeat([2.0, 2.5, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 8.5, 9.0],1,10)'

0 commit comments

Comments
 (0)