6

I have pairs of numbers {a1, b1}, {a2, b2}, {a3, b3}, ..., {aN, bN}

What is the shortest way to compute and plot {a1, b1}, {a2, b1+b2}, {a3, b1+b2+b3},....?

Mary
  • 369
  • 2
  • 9

6 Answers6

14
Accumulate@Array[b, {3}]
(* {b[1], b[1] + b[2], b[1] + b[2] + b[3]} *)

therefore:

{a, b} = Transpose[list];
Transpose[{a, Accumulate[b]}]

Also this will do the job:

Rest@FoldList[{#2[[1]], #1[[2]] + #2[[2]]} &, {0, 0}, list]

or even easier

list[[All,2]]=Accumulate@list[[All,2]]; list
Mike Honeychurch
  • 37,541
  • 3
  • 85
  • 158
11
FoldList[{0, 1} # + #2 &, list]
Simon Woods
  • 84,945
  • 8
  • 175
  • 324
6

thanks to Mike Honeychurch, without pure function:

list = {{a1, b1}, {a2, b2}, {a3, b3}};
Thread[{Thread[list][[1]], Rest@FoldList[Plus, 0, Thread[list][[2]]]}]
(* {{a1, b1}, {a2, b1 + b2}, {a3, b1 + b2 + b3}} *)

and shorter (one expression):

Thread[{list[[All, 1]], Accumulate[list][[All, 2]]}]
garej
  • 4,865
  • 2
  • 19
  • 42
  • Could you please explain a little bit more how Rest@FoldList structure works? – Mary Nov 14 '15 at 17:30
  • 1
    @Maria. Rest just removes first element in the list, i.e. Rest[{1, 2, 3}] gives {2, 3}. @ is a shorthand for head application. So Rest@FoldList[...] is the same as Rest[FoldList[...]]. Finally, FoldList[Plus, 0, {a, b, c}] gives {0, a, a + b, a + b + c}. Now you may see why we need Rest - just to get rid of 0. – garej Nov 14 '15 at 17:55
2

This is another way and an active effort to advertise the ThroughOperator that was developed by @Sjoerd Smit.

To the extend of my knowledge it was first suggested in this answer.

list = {{a1, b1}, {a2, b2}, {a3, b3}};
list[[All, 1]]
ResourceFunction["ThroughOperator"][{Accumulate}][
  list[[All, 2]]] // Flatten
Thread[{%%, %}]

{{a1, b1}, {a2, b1 + b2}, {a3, b1 + b2 + b3}}

bmf
  • 15,157
  • 2
  • 26
  • 63
  • 2
    (+1) ThroughOperator is very flexible, so I hope they consider it as an option in a future version. Nicely done, mate! :-) – E. Chan-López Dec 31 '23 at 01:21
  • 2
    @E.Chan-López thanks a lot! Indeed it is very flexible and bypasses some issues that non-resource functions have. Hopefully, they will consider, but who knows? – bmf Dec 31 '23 at 02:39
2

Another implementation using FoldList and MapAt:

pairs = {{a1, b1}, {a2, b2}, {a3, b3}};

f = FoldList[Apply[Plus]@Flatten@List, Nothing, #] &;

By entering Nothing instead of zero as the initial element in FoldList, we avoid the need to use Rest to remove the first element of the cumulative list. This choice makes the code cleaner and avoids the need to handle special cases.

Transpose@MapAt[f, Transpose@pairs, 2]

({{a1, b1}, {a2, b1 + b2}, {a3, b1 + b2 + b3}})

As the version proposed by @J. M.'s eventual burnout in a comment, but without using Accumulate.

E. Chan-López
  • 23,117
  • 3
  • 21
  • 44
1
list = {{a1, b1}, {a2, b2}, {a3, b3}};

Using SubsetMap (new in 12.0)

SubsetMap[Accumulate, list, {All, 2}]

{{a1, b1}, {a2, b1 + b2}, {a3, b1 + b2 + b3}}

eldo
  • 67,911
  • 5
  • 60
  • 168