# Mediand, std, var to accept function as first argument

**URL:** <https://discourse.julialang.org/t/mediand-std-var-to-accept-function-as-first-argument/8313>\
**Category:** General Usage\
**Tags:** statistics\
**Created:** [January 12, 2018, 11:14am UTC](https://discourse.julialang.org/t/mediand-std-var-to-accept-function-as-first-argument/8313 "2018-01-12T11:14:33Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [January 12, 2018, 11:14am UTC](https://discourse.julialang.org/t/mediand-std-var-to-accept-function-as-first-argument/8313/1 "2018-01-12T11:14:33Z")

</div>

Functions `sum, mean, maximum` etc. accept a function as first argument

```julia
mean(f::Function, v)

  Apply the function f to each element of v and take the mean.

  julia> mean(√, [1, 2, 3])
  1.3820881233139908

```

Functions `std, var, median, extrema` does not. Is there any particular reason for this behaviour?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 12, 2018, 11:29am UTC](https://discourse.julialang.org/t/mediand-std-var-to-accept-function-as-first-argument/8313/2 "2018-01-12T11:29:02Z")

</div>

I think that `mean(::Function, ...)` predates the nice broadcasting syntax (like so many similar convenience forms). This would be a good time to deprecate, then remove it.

As for the other statistics, you can always do `std(f.(x))` and similar, or use a generator. Note that centered moments take two passes (unless you provide the mean), so the choice depends on whether `f` is expensive. For large amounts of data, there is always

> **[GitHub - joshday/OnlineStats.jl: ⚡ Single-pass algorithms for statistics](https://github.com/joshday/OnlineStats.jl)**
>
> ⚡ Single-pass algorithms for statistics. Contribute to joshday/OnlineStats.jl development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![nalimilan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nalimilan/32/147_2.png) [@nalimilan](https://discourse.julialang.org/u/nalimilan)\
**Post date:** [January 12, 2018, 11:31am UTC](https://discourse.julialang.org/t/mediand-std-var-to-accept-function-as-first-argument/8313/3 "2018-01-12T11:31:00Z")

</div>

> [@Tamas\_Papp](#):
>
> I think that mean(::Function, …) predates the nice broadcasting syntax (like so many similar convenience forms). This would be a good time to deprecate, then remove it.

I don’t think broadcasting replaces these methods, since it (currently) allocates a new vector before computing the reduction. On the other hand, generators should be fine (though slightly more verbose).

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 12, 2018, 11:34am UTC](https://discourse.julialang.org/t/mediand-std-var-to-accept-function-as-first-argument/8313/4 "2018-01-12T11:34:36Z")

</div>

> [@nalimilan](#):
>
> generators should be fine (though slightly more verbose).

I frequently wish for a function like

```julia
lazymap(f, xs) = (f(x) for x in xs)

```

Or an annotation that makes broadcast forms return generators.

---

<div class="post-metadata">

**Author:** ![fabiangans](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fabiangans/32/2624_2.png) [@fabiangans](https://discourse.julialang.org/u/fabiangans)\
**Post date:** [January 12, 2018, 12:02pm UTC](https://discourse.julialang.org/t/mediand-std-var-to-accept-function-as-first-argument/8313/5 "2018-01-12T12:02:18Z")

</div>

Does this package help?

> **[GitHub - JuliaArrays/MappedArrays.jl: Lazy in-place transformations of arrays](https://github.com/JuliaArrays/MappedArrays.jl)**
>
> Lazy in-place transformations of arrays. Contribute to JuliaArrays/MappedArrays.jl development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![joshday](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joshday/32/368_2.png) [@joshday](https://discourse.julialang.org/u/joshday)\
**Post date:** [January 12, 2018, 1:56pm UTC](https://discourse.julialang.org/t/mediand-std-var-to-accept-function-as-first-argument/8313/6 "2018-01-12T13:56:03Z")

</div>

I’ll add that (on master) OnlineStats has a new type that filters and transforms a data stream without allocating new arrays.

```julia
julia> s = series(Mean(); transform = abs, filter = !isnan);

julia> fit!(s, [-1, NaN, -3])
▦ AugmentedSeries{0} | EqualWeight | nobs = 2
▦ filter = Base.#57 | transform = abs
└── Mean(2.0)

```

---

<div class="post-metadata">

**Author:** ![davidanthoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/davidanthoff/32/223493_2.png) [@davidanthoff](https://discourse.julialang.org/u/davidanthoff)\
**Post date:** [January 12, 2018, 3:55pm UTC](https://discourse.julialang.org/t/mediand-std-var-to-accept-function-as-first-argument/8313/7 "2018-01-12T15:55:53Z")

</div>

`@map` from Query.jl is a lazy map that should work in these situations.

---

<div class="post-metadata">

**Author:** ![bramtayl](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bramtayl/32/3614_2.png) [@bramtayl](https://discourse.julialang.org/u/bramtayl)\
**Post date:** [January 12, 2018, 6:30pm UTC](https://discourse.julialang.org/t/mediand-std-var-to-accept-function-as-first-argument/8313/8 "2018-01-12T18:30:19Z")

</div>

`Generator` works exactly like `lazymap`. I wish it was exported.

---

<div class="post-metadata">

**Author:** ![bramtayl](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bramtayl/32/3614_2.png) [@bramtayl](https://discourse.julialang.org/u/bramtayl)\
**Post date:** [January 12, 2018, 6:31pm UTC](https://discourse.julialang.org/t/mediand-std-var-to-accept-function-as-first-argument/8313/9 "2018-01-12T18:31:47Z")

</div>

cf [https://github.com/JuliaLang/julia/issues/20402#issuecomment-336280752](https://github.com/JuliaLang/julia/issues/20402#issuecomment-336280752)

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [January 15, 2018, 7:57am UTC](https://discourse.julialang.org/t/mediand-std-var-to-accept-function-as-first-argument/8313/10 "2018-01-15T07:57:33Z")

</div>

Thanks for all the answers! I think the generators solve my use case for now (and they are not that verbose compared to what I came up with without generators `std(cat(3,[fun(i) for i = 1:N]...), 3)` 😂 )

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 15, 2018, 8:22am UTC](https://discourse.julialang.org/t/mediand-std-var-to-accept-function-as-first-argument/8313/11 "2018-01-15T08:22:22Z")

</div>

Perhaps you could make a one line PR? This would be a great feature.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 16, 2018, 11:41am UTC](https://discourse.julialang.org/t/mediand-std-var-to-accept-function-as-first-argument/8313/12 "2018-01-16T11:41:08Z")

</div>

Apparently, generators are not quite like `map`:

> [@Weird behaviour when flattening generator expression with vcat](https://discourse.julialang.org/t/weird-behaviour-when-flattening-generator-expression-with-vcat/8382/10):
>
> A very simple example showing this “problem”: a = [1 , 2, 3] g = (a[i] for i in 1:3) a = [4, 5, 6] collect(g) # Gives 4, 5, 6 # Intuitively I would have expected it to give 1, 2, 3 But this is so fundamental that I would be very surprised if it wasn’t supposed to be like that?

---

<div class="post-metadata">

**Author:** ![bramtayl](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bramtayl/32/3614_2.png) [@bramtayl](https://discourse.julialang.org/u/bramtayl)\
**Post date:** [January 19, 2018, 8:21am UTC](https://discourse.julialang.org/t/mediand-std-var-to-accept-function-as-first-argument/8313/13 "2018-01-19T08:21:28Z")

</div>

I could its worth thinking through though. Maybe there’s a better name than Generator?

---

<div class="post-metadata">

**Author:** ![bramtayl](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bramtayl/32/3614_2.png) [@bramtayl](https://discourse.julialang.org/u/bramtayl)\
**Post date:** [January 19, 2018, 8:23am UTC](https://discourse.julialang.org/t/mediand-std-var-to-accept-function-as-first-argument/8313/14 "2018-01-19T08:23:12Z")

</div>

MappedArrays is a thing too. Hmm

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 19, 2018, 8:24am UTC](https://discourse.julialang.org/t/mediand-std-var-to-accept-function-as-first-argument/8313/15 "2018-01-19T08:24:35Z")

</div>

FWIW, I like `Generator`.

---

<div class="post-metadata">

**Author:** ![bramtayl](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bramtayl/32/3614_2.png) [@bramtayl](https://discourse.julialang.org/u/bramtayl)\
**Post date:** [January 19, 2018, 8:36am UTC](https://discourse.julialang.org/t/mediand-std-var-to-accept-function-as-first-argument/8313/16 "2018-01-19T08:36:57Z")

</div>

What about `Iterators.map`?
