JuliaMath / NaNMath.jl

Julia math built-ins which return NaN and accumulator functions which ignore NaN
Other
52 stars 26 forks source link

Array of Numbers + Mean of Absolute Values #49

Open ptoche opened 3 years ago

ptoche commented 3 years ago

For some personal project, I ended up lifting your mean (Thanks!) and doing the following, for two reasons

  1. support arrays of integers
  2. calculate the mean of absolute values

Maybe there was a better way, but this is what I came up with. For the record.

# array_arithmetic.jl

"""
mean(AbstractArray{T})`

Returns the arithmetic mean of all elements in the array, ignoring NaNs.
"""
function mean(x::AbstractArray{T}) where T<:Number
    return mean_count(x)[1]
end

"""
`mean_abs(AbstractArray{T})`

Returns the arithmetic mean of the absolute values of all elements in the array, ignoring NaNs.
"""
function mean_abs(x::AbstractArray{T}) where T<:Number
    return mean_count(x, absolute = true)[1]
end
"""
Returns a tuple of the arithmetic mean of all elements in the array, ignoring NaNs,
and the number of non-NaN values in the array.
"""
function mean_count(x::AbstractArray{T}; absolute = false) where T<:Number
    z = zero(eltype(x))
    sum = z
    count = 0
    @simd for i in x
        count += ifelse(isnan(i), 0, 1)
        if absolute; i = abs(i); end
        sum += ifelse(isnan(i), z, i)
    end
    result = sum / count
    return (result, count)
end

A = [1 2 3 4 5; 6 7 8 9 10]
mean(A)
mean_abs(A)

mean(convert.(Float64, A))
mean_abs(convert.(Float64, A))

B = [1 -2 3 -4 5; -6 7 -8 9 -10]
mean(B)
mean_abs(B)