4
$\begingroup$

How could I use BinLists to give elements indices in list instead of giving the list elements belonging to each bin ?

Thanks.

$\endgroup$
3
$\begingroup$

using the 2d form of BinLists ( note the first dimension binspec is cooked up so there is just one bin )

 list = RandomReal[{0, 1}, {20}];
 binspec = {0, 1, .1};
 (#[[All, 1]] & /@ First@BinLists[ MapIndexed[{First@#2, #} &, #] ,
       {0, Length@# + 1, Length@# + 1}, binspec]) &@list

{{1, 10, 20}, {6}, {7, 15}, {4}, {5, 12, 17}, {11}, {14, 18}, {9}, {2, 3, 8, 16, 19}, {13}}

 ( list[[#]] & /@ % ) == BinLists[ list , binspec] 

True

You could simply do this as well:

 Union@Flatten@(Position[ list, #]  & /@ # ) & /@ BinLists[list, binspec]
$\endgroup$
1
  • $\begingroup$ Thanks for this black magic.. unreadable, but apparently it works! ;) $\endgroup$ – Thomas Fankhauser Apr 19 '15 at 11:36
0
$\begingroup$

For my own question and self-answer I wrote the following utility function.

BinPositions[vals_, brakes_, sameTest_] :=
 Map[val \[Function] 
   Catch@Module[{lo = 1, mid, hi = Length[brakes], el, res},
     While[lo <= hi, Which[
       TrueQ@sameTest[val, el = brakes[[mid = Floor[(lo + hi)/2]]]], 
       Throw[mid],
       el > val, hi = mid - 1,
       True, lo = mid + 1]];
     lo - 1/2],
  vals]

The semanthic is sligtly different from previous answer, but, maybe, it can be adapted to your scenario.

list = RandomReal[{0, 100}, {20}]
brakes = Union@RandomInteger[{0, 100}, 10]
Floor@BinPositions[list, brakes, SameQ]

{48.311, 40.7217, 50.8321, 73.2729, 24.7769, 42.4868, 12.475, 7.04288, 3.22704, 89.9731, 82.0066, 73.565, 83.0642, 45.4985, 81.3878, 55.5902, 82.3677, 68.8531, 57.4473, 83.1311}

{6, 20, 28, 32, 35, 52, 73, 82, 95}

{5, 5, 5, 7, 2, 5, 1, 1, 0, 8, 8, 7, 8, 5, 7, 6, 8, 6, 6, 8}

$\endgroup$
0
$\begingroup$

Using the function positionDuplicates from this answer by @Szabolcs

ClearAll[positionDuplicates, dispatchF, positionBins]
positionDuplicates[list_] :=  GatherBy[Range@Length[list], list[[#]] &]; 

dispatchF = Dispatch @ Thread[DeleteDuplicates[#] -> positionDuplicates[#]] &;
positionBins = Union @@@ (BinLists[#, #2] /. dispatchF[#1]) &;

Example 1:

data = RandomInteger[5, 17]

{5, 4, 1, 3, 0, 3, 0, 0, 5, 5, 0, 0, 5, 1, 5, 5, 0}

BinLists[data, 3] (* change `3` to your choice of binspecs *)

{{}, {1, 0, 0, 0, 0, 0, 1, 0}, {5, 4, 3, 3, 5, 5, 5, 5, 5}}

positionBins[data, 3]

{{}, {3, 5, 7, 8, 11, 12, 14, 17}, {1, 2, 4, 6, 9, 10, 13, 15, 16}}

Example 2:

BinLists[data, {{0, 2, 4, 6}}]

{{1, 0, 0, 0, 0, 0, 1, 0}, {3, 3}, {5, 4, 5, 5, 5, 5, 5}}

positionBins[data, {{0, 2, 4, 6}}]

{{3, 5, 7, 8, 11, 12, 14, 17}, {4, 6}, {1, 2, 9, 10, 13, 15, 16}}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.