StatsBase.jl icon indicating copy to clipboard operation
StatsBase.jl copied to clipboard

Inconsistencies between `mean` and `mean!` when using 0-Arrays.

Open kellertuer opened this issue 2 years ago • 2 comments

I just stumbled upon some inconsistencies between mean and mean! and I am wondering whether this is a bug – since we try to use both those methods in a setting where I would expect them to work consistently. Here is a small example.

using StatsBase
x = [fill(1.0), fill(2.0), fill(3.0), fill(4.0)]
w = pweights(ones(length(x)) / length(x))
y = mean(x,w)

which returns a

0-dimensional Array{Float64, 0}:
2.5

So consistently I would have expected mean! to do the same if I pass y as the return value, i.e.

mean!(y,x,w)

but it reports

ERROR: ArgumentError: dims argument must be provided
Stacktrace:
 [1] _mean!(R::Array{Float64, 0}, A::Vector{Array{Float64, 0}}, w::ProbabilityWeights{Float64, Float64, Vector{Float64}}, dims::Nothing)
   @ StatsBase ~/.julia/packages/StatsBase/WLz8A/src/weights.jl:657

But even if I provide the dims I get for

mean!(y,x,w; dims=1)
ERROR: MethodError: no method matching +(::Float64, ::Array{Float64, 0})
For element-wise addition, use broadcasting with dot syntax: scalar .+ array

Closest candidates are:
  +(::Any, ::Any, ::Any, ::Any...)
   @ Base operators.jl:578
  +(::T, ::T) where T<:Union{Float16, Float32, Float64}
   @ Base float.jl:408
  +(::Union{Float16, Float32, Float64}, ::BigFloat)
   @ Base mpfr.jl:423
  ...

Stacktrace:
  [1] macro expansion
    @ ~/.julia/packages/StatsBase/WLz8A/src/weights.jl:528 [inlined]
[...]

Ah, I noticed that the same happens, also in the unweighted case, just that it skips the dimension error and directly reports the last.

kellertuer avatar Dec 18 '23 15:12 kellertuer

The error ArgumentError: dims argument must be provided is thrown on purpose when dims is not passed. This seems to be intended, so I don't know if this should be changed.

The ERROR: MethodError: no method matching +(::Float64, ::Array{Float64, 0}) appears because you assigned 2.5 to y by doing y = mean(x,w). So typeof(y) == Float64. If you do mean!([y],x,w; dims=1) instead, no error is thrown and the y is overwritten by the new value.

JMulder99 avatar Nov 17 '24 16:11 JMulder99

Thanks for the explanations. I am still a bit surprised that the result of mean or in other words the zero element vector I would expect can not be used in-place for mean!.

Or to be precise: The result of the first y = mean(x,w)is not a flor64, it is a zero-dimensional array. But I can not use the same result type for mean!.

Same for the dims – who do I have to pass that for mean! but not for mean?

The inconsistency win those two methods is what I find a bit strange, I would expect them to work consistently. If both would complain about the dimension, that would be fine with me.

kellertuer avatar Nov 17 '24 16:11 kellertuer