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