Services & Resources / Wolfram Forums / MathGroup Archive
-----

MathGroup Archive 2012

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

Search the Archive

Re: Extension to BinLists Function

  • To: mathgroup at smc.vnet.net
  • Subject: [mg124036] Re: Extension to BinLists Function
  • From: Heike Gramberg <heike.gramberg at gmail.com>
  • Date: Fri, 6 Jan 2012 04:19:28 -0500 (EST)
  • Delivered-to: l-mathgroup@mail-archive0.wolfram.com
  • References: <201201051057.FAA14691@smc.vnet.net>

For your second example you could do something like

index[bp_] :=  Function[{x}, Evaluate@Piecewise@ MapIndexed[{#2[[1]], #1[[1]] <= x < #1[[2]]} &, Partition[bp, 2, 1]]]

bins[lst_, breakPoints_] := With[{fx = index[breakPoints]},
  Flatten[#, 1] & /@ Reap[Sow[#, fx[#[[1]]]]; & /@ lst, Range[Length[breakPoints] - 1]][[2]]]

then bins[data1, breakPoints] returns

{{{1, 0.936229}, {1, 0.301525}}, {{3, 0.128096}, {2, 0.393583}, {4, 0.503822}, {2, 0.0068356}}, {{5, 0.253597}, {6, 0.0835316}}, {}}

Here, index[] is just a helper function such that index[breakPoints][x] returns the index of the bin x belongs.

Heike.

On 5 Jan 2012, at 11:57, Don wrote:

> Hello,
>
> The documentation shows examples of BinLists putting into
> bins one dimensional vectors of numbers such as the following
> example:
>
> data = {1,3,2,1,4,5,6,2};
> breakPoints =  {-Infinity,2,5,7,Infinity};
>
> BinLists[data, {breakPoints}]
>
> which returns:
>
> {{1, 1}, {3, 2, 4, 2}, {5, 6}, {}}
>
> I would like to put into bins entire sublists of data
> of arbitray  depth  such as the following
> example where every sublist is 2-dimensional:
>
> data1 = Transpose[{data, Table[Random[],{Length[data]}]}]
>
> which results for the values of data1: 
>
> =
{{1,0.936229},{3,0.128096},{2,0.393583},{1,0.301525},{4,0.503822},{5,0.253597},{6,0.0835316},{2,0.0068356}}
>
> In this simple example, the sublists are binned based on the value of the first element
> of every sublist. 
>
> The result, using the same breakpoints (this time applied to the first
> element of every sublist as in the example above),
> should be:
>
>
> =
{{{1,0.936229},{1,0.301525}},{{3,0.128096},{2,0.393583},{4,0.503822},{2,0.0068356}},{{5,0.253597},{6,0.0835316}},{}}
>
>
> The binLists function below does this job.
> But, it uses brute force in the form of a couple of
> nested For functions to accomplish this. 
> Is there a more efficient way  of binning
> sublists of arbitrary depth?
>
> Thank you.
>
> Don
>
> =========================
>
> For the second example above, which uses the
> binLists function defined below, the inputs to the  binLists
> function  are:
>
> array = data1
> breakPts = {2, 5, 7}
> pos = {1}
>
>
> binLists[data1, breakPts, pos]
>
> returns
>
> 
{{{1,0.936229},{1,0.301525}},{{3,0.128096},{2,0.393583},{4,0.503822},{2,0.0068356}},{{5,0.253597},{6,0.0835316}},{}}
>
> which is the correct result.
>
> =========================
>
> Definition of binLists:
>
> Remove[binLists ];
>
> binLists[array_List, breakPts_List, pos_List:{}  ] :=
> Module[{},
>
>
>
>  breakPtIntervalV= Partition[Join[{-Infinity},breakPts,{Infinity}], 2, 1];
>
>  nIntervals = Length[breakPtIntervalV];
>
>  bins = Table[{},{nIntervals}];
>
>  (*
>  elemV holds the element from each sublist in array that
>     that binning is to be a function of
>  *)  
>
>  If[Length[pos] > 0,
>        elemV = #[[Apply[Sequence, pos]]]& /@ array,
>        elemV = array
>    ];(* If Length *)
>
>  For[j = 1, j<= Length[array], ++j,
>
>      For[k=1, k<=nIntervals, ++k,
>
>         If[
>         elemV[[j]] >= breakPtIntervalV[[k,1]] &&
>         elemV[[j]] < breakPtIntervalV[[k,2]],
>            AppendTo[bins[[k]], array[[j]]]
>            Continue[]
>            ]
>
>
>        ];(* For k *)
>
>  ];(* For j *)
>
>  Return[bins]
>
>  ](* End Module binLists  *)
>




  • Prev by Date: Re: drawing polygon diagonals
  • Next by Date: Re: Extension to BinLists Function
  • Previous by thread: Extension to BinLists Function
  • Next by thread: Re: Extension to BinLists Function