Re: Creating sub-list based on a given criterion
- To: mathgroup at smc.vnet.net
- Subject: [mg110592] Re: Creating sub-list based on a given criterion
- From: Peter Pein <petsie at dordos.net>
- Date: Sat, 26 Jun 2010 08:42:22 -0400 (EDT)
- References: <i0495h$5lm$1@smc.vnet.net>
Am Sat, 26 Jun 2010 07:10:41 +0000 (UTC) schrieb Dimitris Emmanoulopoulos <demmanoulopoulos at hotmail.com>: > Hello > > I was wondering if there is any straightforward way to bin a list > into sub-lists containing those elements that full-fill a given > criterion. Consider the following list > > ds= > {{{0,0,1},{1,0,-1},{2,0,-1},{3,0,-1},{4,0,-1},{5,588,-1},{6,2345,1},{7,2418,1},{8,2323,1},{9,2179,1}},{{480,23,1},{487,23,1},{470,29,1},{478,32,1},{468,25,1},{498,19,-1},{494,15,1},{496,20,1},{455,33,1},{462,27,1}},{{781,1,1},{779,1,1},{784,0,1},{778,0,1},{766,1,-1},{735,1,-1},{758,1,-1},{733,2,-1},{716,0,-1},{794,1,1}}} > > The criterion is that the sum of the second elements in each new > sub-list should be at least 25? > > After the re-binning we should get something like: > > {{0,0,1},{1,0,-1},{2,0,-1},{3,0,-1},{4,0,-1},{5,588,-1}} > {6,2345,1} > {7,2418,1} > {8,2323,1} > {9,2179,1} > {{480,23,1},{487,23,1}} > {470,29,1} > {478,32,1} > {468,25,1}, > {498,19,-1},{494,15,1}, > {496,20,1},{455,33,1} > {{462,27,1},{781,1,1},{779,1,1},{784,0,1},{778,0,1},{766,1,-1},{735,1,-1},{758,1,-1},{733,2,-1},{716,0,-1},{794,1,1}}} > > The first bin has a total of the second elements 588, the second > 2345, the third 2418,...,the sixth 46, the seventh 29, =C3=A2=E2=82=AC=C2= =A6,the > eleventh 53, and the last one 35. > > In other words, imagine that these are the results of a counting > experiment and the second element in every entry (in ds) corresponds > to counts. The question is how can we re-bin the data in order to > have at least 25 counts per new-bin? Of course it is straightforward > to do it using a Do-loop, but I was wondering if there is any simpler > way to do it using the efficient Mathematica syntax in an > =C3=A2=E2=82=AC=C5=93one-liner expression=C3=A2=E2=82=AC_. > > Thanks a lot > Dimitris > Hi Dimitris, I did not manage it in one line but at least looks like Mathematica ;-) In[2]:= d2 = Block[ {sum = 0, lst = Flatten[ds, 1]}, lst = Map[First, Split[ Map[{#, If[(sum += #[[2]]) >= 25, sum=0; False, True]}&, lst], Last[#1]&], {2}]; If[Length[lst] >= 2 && Total[Last[lst][[All, 2]]] < 25, Join[Drop[lst, -2], {Join @@ Take[lst, -2]}], lst] ] Out[2]= { {{0,0,1},{1,0,-1},{2,0,-1},{3,0,-1},{4,0,-1},{5,588,-1}}, {{6,2345,1}}, {{7,2418,1}}, {{8,2323,1}}, {{9,2179,1}}, {{480,23,1},{487,23,1}}, {{470,29,1}}, {{478,32,1}}, {{468,25,1}}, {{498,19,-1},{494,15,1}}, {{496,20,1},{455,33,1}}, {{462,27,1},{781,1,1},{779,1,1},{784,0,1},{778,0,1}, {766,1,-1},{735,1,-1},{758,1,-1},{733,2,-1},{716,0,-1}, {794,1,1}} } I guess a loop based approach would be faster in execution but I did not try it. Cheers, Peter