@@ -43,18 +43,6 @@ julia> mean(skipmissing([1, missing, 3]))
4343"""
4444mean (itr) = mean (identity, itr)
4545
46- struct Counter{F} <: Function
47- f:: F
48- n:: Base.RefValue{Int}
49- end
50- Counter (f:: F ) where {F} = Counter {F} (f, Ref (0 ))
51- (f:: Counter )(x) = (f. n[] += 1 ; f. f (x))
52-
53- struct DivOne{F} <: Function
54- f:: F
55- end
56- (f:: DivOne )(x) = f. f (x)/ 1
57-
5846"""
5947 mean(f, itr)
6048
@@ -71,13 +59,23 @@ julia> mean([√1, √2, √3])
7159```
7260"""
7361function mean (f, itr)
74- if Base. IteratorSize (itr) === Base. SizeUnknown ()
75- g = Counter (DivOne (f))
76- result = mapfoldl (g, add_mean, itr)
77- return result/ g. n[]
78- else
79- return mapfoldl (DivOne (f), add_mean, itr)/ length (itr)
62+ y = iterate (itr)
63+ if y === nothing
64+ return Base. mapreduce_empty_iter (f, + , itr,
65+ Base. IteratorEltype (itr)) / 0
8066 end
67+ count = 1
68+ value, state = y
69+ f_value = f (value)/ 1
70+ total = Base. reduce_first (+ , f_value)
71+ y = iterate (itr, state)
72+ while y != = nothing
73+ value, state = y
74+ total += _mean_promote (total, f (value))
75+ count += 1
76+ y = iterate (itr, state)
77+ end
78+ return total/ count
8179end
8280
8381"""
@@ -182,24 +180,20 @@ mean(A::AbstractArray; dims=:) = _mean(identity, A, dims)
182180
183181_mean_promote (x:: T , y:: S ) where {T,S} = convert (promote_type (T, S), y)
184182
185- add_mean (x, y) = Base. add_sum (x, _mean_promote (x, y))
186-
187- Base. reduce_empty (:: typeof (add_mean), T) = Base. reduce_empty (Base. add_sum, T)
188- Base. mapreduce_empty (g:: DivOne , :: typeof (add_mean), T) = Base. mapreduce_empty (g. f, Base. add_sum, T)/ 1
189- Base. mapreduce_empty (g:: Counter{<:DivOne} , :: typeof (add_mean), T) = Base. mapreduce_empty (g. f. f, Base. add_sum, T)/ 1
190-
191-
192183# ::Dims is there to force specializing on Colon (as it is a Function)
193184function _mean (f, A:: AbstractArray , dims:: Dims = :) where Dims
185+ isempty (A) && return sum (f, A, dims= dims)/ 0
194186 if dims === (:)
195- result = mapreduce (DivOne (f), add_mean, A, dims= dims)
196187 n = length (A)
188+ else
189+ n = mapreduce (i -> size (A, i), * , unique (dims); init= 1 )
190+ end
191+ x1 = f (first (A)) / 1
192+ result = sum (x -> _mean_promote (x1, f (x)), A, dims= dims)
193+ if dims === (:)
197194 return result / n
198195 else
199- result = mapreduce (DivOne (f), add_mean, A, dims= dims)
200- n = prod (i -> size (A, i), unique (dims); init= 1 )
201- result ./= n
202- return result
196+ return result ./= n
203197 end
204198end
205199
0 commit comments