Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

The problem I have is really basic but I just can't get my head around it.

Suppose I have a list of ordered pairs

A = {{a, b}, {c, d}, {e, f}, {g, h}, ...}.

I am looking for a function that will give me the average of partial sums of the second element of each pair, like so:

f[1] = b/1 = A[[1, 2]]/1
f[2] = (b+d)/2 = (A[[1, 2]] + A[[2, 2]])/2
f[3] = (b+d+f)/3 = (A[[1, 2]] + A[[2, 2]] + A[[3, 2]])/3
....
f[n] = ?

Thank you for your help.

share|improve this question
1  
Mean /@ FoldList[Flatten[{##}] &, A[[All, 2]]] – Dr. belisarius Jan 5 at 18:53
2  
ReplaceList[A[[All, 2]], {x__, y___} :> Mean@{x}] – Dr. belisarius Jan 5 at 18:59
    
@Dr. belisarius. Sorry, I didn't intend to rip off your first comment in my answer. You should post your second comment as answer though, since it is very readable. – Sascha Jan 5 at 19:02
    
@Sascha No problem :) – Dr. belisarius Jan 5 at 19:03
1  
note the best approach may differ if the list is large and you just want a particular n vs if you want to tabulate f for all n.. – george2079 Jan 5 at 20:12
up vote 7 down vote accepted
      Accumulate@Last@Transpose[A]/Range@Length@A

{b, (b + d)/2, 1/3 (b + d + f), 1/4 (b + d + f + h)}

share|improve this answer
    
Best answer so far in terms of readability and simplicity. I didn't know about Accumulate, thanks! – Sascha Jan 5 at 20:54
list = {{a, b}, {c, d}, {e, f}, {g, h}};

Mean[Take[Last /@ list, #]] & /@ Range@Length@list

enter image description here

share|improve this answer
Clear[f,g, list];
list= {{a,b}, {c, d}, {e, f}, {g, h}}

f[list_,n_]:=Part[FoldList[Plus,Last@Transpose@list] / Range@Length@list, n]

or another version I personally prefer (sadly no operator forms for FoldList and Part)

g[list_, n_]:=list //Transpose
                   //Last
                   //FoldList[Plus, #]& 
                   //Divide[#,Range@Length@list]& 
                   //Extract[n]

I especially like that one can out-comment or partially copy the function definition to find out what the function does step by step

Edit: Instead of //Extract[n] previously //Part[#,n]& was used in the definition of g. Without regard for a potential difference in performance I now like Extract[n] better.

share|improve this answer
    
I remember someone else proposing and/or supporting this use of post-fix notation. Did you arrive at this style yourself or did you read a post or paper recommending it? (I ask because I'd like to re-read that but I cannot find it.) – Mr.Wizard Jan 6 at 8:11
    
@Mr.Wizard. I saw this form first in @Simon Woods answer to this question on the use of the new operator forms. The formatting of g I choose first since not all postfix-operators fit into a single line. In retrospective this may make it even more readable for people that are familiar with imperative programming style. – Sascha Jan 6 at 9:16
    
@Mr.Wizard I think I found the blog post you were referring to in your comment (had not seen it before though). It was postet as a comment to your answer in the same question that I linked in my previous comment. Here it is – Sascha Jan 6 at 9:56

Just to give one more solution: One can use the Accumulate function here, which sums up the parts, then take the Mean (simply by dividing). So I think with

list = {{a, b}, {c, d}, {e, f}, {g, h}}

the command

Accumulate @ list[[All, 2]] / Range[Length@list]

will do the job.

share|improve this answer

A solution that does not make use of the length of the list and calculates for the whole list.

m = MapAt[Mean, {2 ;;}]@FoldList[Flatten@*List, list[[All, 2]]]
(* {b, (b + d)/2, 1/3 (b + d + f), 1/4 (b + d + f + h)} *)

If you need to just calculate for a particular $n$ then

n = 2;
Mean[list[[1 ;; n, 2]]]
(* (b + d)/2 *)

Hope this helps.

share|improve this answer

So many roads to Rome...

list = {{a, b}, {c, d}, {e, f}, {g, h}};

MapIndexed[Divide[#1, #2] &, Accumulate[(Last /@ list)]] // Flatten

(*{b, (b + d)/2, 1/3 (b + d + f), 1/4 (b + d + f + h)}*)
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.