Julia: Method to apply a function to each element before taking mean along a dimension

Created on 6 Feb 2018  路  4Comments  路  Source: JuliaLang/julia

There is already a method to apply a function to each element when taking the mean:
mean(f, A)

And a method to take the mean along a dimension:
mean(A, 1)

Is there any interest in providing a method that combines the two above?
mean(f, A, 1)

I wrote the methods to do this because I was trying to avoid allocating a temporary array when calculating things like mean(x.^2, 1). I feel like this method is a pretty natural extension to what is already provided, so I was surprised to see it wasn't already available.

I've opened this issue to first discuss if there is any need/desire for these additions, and if so I could put together a PR. I've included a WIP of my proposed addition below. I can also provide benchmarks and tests if there is any interest.

"""
    mean(f, A, region)

Apply the function `f` to each element of `A`, and compute the mean along dimension in `region`.
"""
function Base.mean(f::Function, a::AbstractArray, region::Int)
    x = Base.mapreducedim(f, +, a, region)
    n = 1 // length(x)
    x .= x .* n 

    return x
end

"""
    mean!(f, r, A)

Apply `f` to each element of A, and compute the mean over the singleton dimensions of `r`, and write the results to `r`.
"""
function Base.mean!(f::Function, r::AbstractArray{T}, a::AbstractArray) where {T<:Number}
    fill!(r, zero(T))
    x = Base.mapreducedim!(f, +, r, a)
    n = 1 // length(x)
    x .= x .* n 

    return x
end

Most helpful comment

We already provide this API for sum, prod, minimum, and maximum (maybe others as well), so telling people to use a package just for mean is silly.

All 4 comments

This is a reasonable request, but also note that there are other ways to achieve this:

using MappedArrays
b = mappedarray(f, a)
mean(b, 1)

If we do this then we should make the API match for var and std, which accept dimensions but not mapping functions.

mappedarray seems like a much better way to achieve this

We already provide this API for sum, prod, minimum, and maximum (maybe others as well), so telling people to use a package just for mean is silly.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tkoolen picture tkoolen  路  3Comments

iamed2 picture iamed2  路  3Comments

i-apellaniz picture i-apellaniz  路  3Comments

manor picture manor  路  3Comments

dpsanders picture dpsanders  路  3Comments