Re: Appending to Lists
- To: mathgroup at smc.vnet.net
- Subject: [mg27058] Re: Appending to Lists
- From: "Allan Hayes" <hay at haystack.demon.co.uk>
- Date: Sat, 3 Feb 2001 04:58:54 -0500 (EST)
- References: <95b686$4mr@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
James, b = Table[Random[], {10000}]; c = Table[Random[Integer, {1, 100}], {10000}]; Your code bin1[b_, c_] := Block[{a = {}}, Do[AppendTo[a, Flatten[Part[b, #] & /@ Position[c, i]]], {i, 1, Max[c]}]; a ] (r1 = bin1[b, c]); // Timing {59.26 Second, Null} Two alternatives: This give the same ressult as bin1: bin2[b_, c_] := Part[b, #] & /@ ((Join @@ Position[c, #]) & /@ Range[1, Max[c]]) (r2 = bin2[b, c]); // Timing {5.05 Second, Null} This one sorts the bins: bin3[b_, c_] := Split[Sort[Transpose[{c, b}]], #1[[1]] === #2[[1]] &][[All, All, -1]] (r3 = bin3[b, c]); // Timing {2.58 Second, Null} Test Sort /@ r1 === Sort /@ r2 === r3 True The padding with zeros is quite quick for this example(few bins) pad[mat_] := With[{n = Max[Length /@ mat]}, PadRight[#, n, 0.] & /@ mat]; pr3 = pad[r3]; // Timing {0.05 Second, Null} Spot check Short[Take[pr3, {2}], 3] {{0.0126083, 0.0146036, 0.0247964, 0.038953, \[LeftSkeleton]121\[RightSkeleton], 0., 0., 0., 0.}} -- Allan --------------------- Allan Hayes Mathematica Training and Consulting Leicester UK www.haystack.demon.co.uk hay at haystack.demon.co.uk Voice: +44 (0)116 271 4198 Fax: +44 (0)870 164 0565 "James Jones" <j.k.jones at dl.ac.uk> wrote in message news:95b686$4mr at smc.vnet.net... > Hi, > > I have a function that creates a list (a) from another list (b). The list > elements are re-grouped in the new list according to a third list (c). A > Position command is applied to list (c) for an element, then with this > output the list (a) is created from list (b) at positions given by the > element position data, list (c). This is repeated for the large number of > elements in the original lists. > The Position command is necessary as different elements appear in the list a > different number of times. > However, with the large number of elements in the lists (approx 50,000 for a > simple list), this method is _very_ slow. > If any one can give me help in speeding this process up I would be very > grateful. > > The data sets would look like this > > b c > > 0.2 1 > 0.6 2 > 1.2 3 > -0.2 1 > 0.5 2 > 0.3 1 > 0.7 2 > -0.2 1 > -0.6 1 > > A List would then be created from this data ( the list (a) ) containing > vectors for 1, 2 and 3. The data in (b) is not important, and the order in > which elements in (c) drop out is not set. > In this case the (a) list should look like > > a = { { 0.2, -0.2, -0.2, -0.6} , {0.6, 0.5, 0.7} , { 1.2 } } > > My current function looks like this > > Do[AppendTo[xfinal, > Flatten[Part[X, #] & /@ > Position[Global`PARTICLE, i]]], {i, 1, > Max[PARTICLE]}]; > > where xfinal is an (a) list, i.e. to be created. > X is the (b) list , i.e. to be addressed, and > PARTICLE is the (c) list. It is referenced by number. > > and it is very slow! > > Also, after producing this list, the different vector elements need to be > made the same length, and so 0.0 are added to the ends of all vector > elements shorter than the longest. My current function for doing this looks > like > > table = Table[0.0, {Length[First[long]]}]; Print["Table Created!"]; > > Do[If[Length[Part[xfinal, i]] < Length[First[long]], > AppendTo[Part[xfinal, i], > Drop[table, (Length[Part[xfinal, i]])] ]], {i, 2, > Length[xfinal]}]; > > where list (long) just sorts the list elements according to length. > > This function is also very slow, and I was wondering, again, if anyone knew > a faster way of implementing this. Is the production of a table, once, and > then dropping bits off and appending the fastest method? Of course this > needs to be done tens of thousands of times per set of data so any small > speed increase would be very helpful ;-> > > Again, any help much appreciated, > > James Jones > Daresbury Laboratory > >