Re: how to sum lists of unequal length?
- To: mathgroup at smc.vnet.net
- Subject: [mg70401] Re: how to sum lists of unequal length?
- From: dimmechan at yahoo.com
- Date: Sun, 15 Oct 2006 00:19:54 -0400 (EDT)
- References: <egq2th$84h$1@smc.vnet.net>
As regards myself, your query confused me for much time until to reach a solution. I must admit that my first thinking was Thread[{a1, a2, a3} + {b1, b2, b3, b4, b5}] Thread::tdlen : Objects of unequal length in {a1, a2, a3} + {b1, b2, b3, b4,b5} cannot be combined {a1, a2, a3} + {b1, b2, b3, b4, b5} based mistakenly on the result Thread[{a1, a2, a3} + d + {b1, b2, b3} + k] {a1 + b1 + d + k, a2 + b2 + d + k, a3 + b3 + d + k} After I notice something so basic that I don't know how I forget it. Information[Thread] "Thread[f[args]] \"threads\" f over any lists that appear in args. Thread[f[args], h] threads f over any objects with head h that appear in args. Thread[f[args], h, n] threads f over objects with head h that appear in the first n args. Thread[f[args],h, -n] threads over the last n args. Thread[f[args], h, {m, n}] threads over arguments m through n." Attributes[Thread] = {Protected} with all the elements in the specified args whose heads are h must be of the same length. Anyway, although I do believe that it must be something simpler, here is my solution (after many unsuccesful attempts!). First of all consider the following list, containing sublists of pseudorandom numbers of pseudonumber length dat = Table[Random[Integer, {0, 10}], {5}, {Random[Integer, {1, 10}]}] {{6, 4, 5, 0, 9, 2, 10}, {5, 6, 9, 3, 7}, {10}, {7, 8, 1}, {1}} But before I show you my solution, let me analyze a little the code. Here is the length of each sublist. Length /@ dat {7, 5, 1, 3, 1} Here I add 0s elements in the sublist that have length smaller than 7. dat //. {a___, {x___}, b___} :> {a, Flatten[{x, Table[0, {Max[%] - Length[{x}]}]}], b} /; Length[{x}] < Max[%] {{6, 4, 5, 0, 9, 2, 10}, {5, 6, 9, 3, 7, 0, 0}, {10, 0, 0, 0, 0, 0, 0}, {7, 8, 1, 0, 0, 0, 0}, {1, 0, 0, 0, 0, 0, 0}} And here is the desired sum. I have use HoldForm so that you can see which elements are summed. MapThread[HoldForm[Plus[##1]] & , %] {6+5+10+7+1,4+6+0+8+0,5+9+0+1+0,0+3+0+0+0,9+7+0+0+0, 2+0+0+0+0,10+0+0+0+0} Let's construct now the proper one-liner sumListsofUneqLength[lis_List] := MapThread[Plus, lis //. {a___, {x___}, b___} :> {a, Flatten[{x, Table[0, {Max[Length /@ lis] - Length[{x}]}]}], b} /;Length[{x}] < Max[Length /@ lis]] (*CHECK*) sumListsofUneqLength[dat] {29, 18, 15, 3, 16, 2, 10} lst1 = Table[a[i], {i, 3}] lst2 = Table[b[i], {i, 5}] lst3 = Table[c[i], {i, 10}] {a[1], a[2], a[3]} {b[1], b[2], b[3], b[4], b[5]} {c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9], c[10]} sumListsofUneqLength[{lst1, lst2, lst3}] {a[1] + b[1] + c[1], a[2] + b[2] + c[2], a[3] + b[3] + c[3], b[4] +c[4], b[5] + c[5], c[6],c[7], c[8], c[9], c[10]} Let's check a bigger list of sublists bigdat=Table[Random[Integer,{0,10}],{5000},{Random[Integer,{1,10}]}]; Timing[sumListsofUneqLength[bigdat]] {11.188 Second,{25408,25217,24856,25032,25319,25020,24821, 25323,25195,25389}} Regads Dimitris