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 *)
>
- References:
- Extension to BinLists Function
- From: Don <donabc@comcast.net>
- Extension to BinLists Function