MathGroup Archive 2010

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Creating sub-list based on a given criterion

  • To: mathgroup at smc.vnet.net
  • Subject: [mg110600] Re: Creating sub-list based on a given criterion
  • From: Leonid Shifrin <lshifr at gmail.com>
  • Date: Sun, 27 Jun 2010 04:56:40 -0400 (EDT)

Hi Dimitris,

here is a solution based on repeated application of rules:

In[1] :==

Module[{temp, left},
 Flatten[ds, 1] //.
   {{done___temp, Shortest[x__List] /; Total[{x}[[All, 2]]] >== 25,
      y___} :> {done, temp[x], y},
    {done___temp, rest : {_, _, _} ..} :> {done, left[rest]}} /.
  temp | left -> List]

Out[1]== {{{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}}}

Note that the last list may not satisfy your criteria and in general simply
gathers leftovers. You can convert it to a function as follows:

Clear[rebin];
rebin[binned : {{{_?NumericQ, _?NumericQ, _?NumericQ} ..} ..},
   minValue_?NumericQ] :==
  Module[{temp,left},
   Flatten[binned,
      1] //. {{done___temp,
        Shortest[x__List] /; Total[{x}[[All, 2]]] >== minValue,
        y___} :> {done, temp[x], y},
      {done___temp, rest : {_, _, _} ..} :> {done, left[rest]}}
    /. temp|left -> List];

Then you just call,

rebin[ds, 25]

Generally, this kind of problems seem to be harder to solve in a very
succinct manner in Mathematica without resorting to side effects, since in
splitting the list some non-trivial run-time information is required. For
example, you can solve the problem much easier if you allow side effects to
be used:

In[4]:==
Module[{sum == 0},
 Split[Flatten[ds,
   1], (sum +== #1[[2]]; If[sum >== 25, sum == 0; False, True]) &]]

Out[4]==
{{{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}}}

Hope this helps.

Regards,
Leonid


On Sat, Jun 26, 2010 at 12:10 AM, Dimitris Emmanoulopoulos <
demmanoulopoulos at hotmail.com> wrote:

> 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,24=
18,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, th=
e
> third 2418,...,the sixth 46, the seventh 29, =85,the eleventh 53, and the=
 last
> one 35.
>
> In other words, imagine that these are the results of a counting experime=
nt
> 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 count=
s
> 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 =93one-liner expression=94.
>
> Thanks a lot
> Dimitris
>
>


  • Prev by Date: Re: Image processing Questions
  • Next by Date: Re: function local/private to another function?
  • Previous by thread: Re: Creating sub-list based on a given criterion
  • Next by thread: how to automatically include own package into different demonstration