Raccogliere tutti gli elementi in un elenco di float in gruppi definiti da un elenco di intervalli?

Aug 24 2020

Una domanda simile riguardante i numeri interi è stata posta e ha risposto qui . Tuttavia, poiché tutte le soluzioni si basano sulla generazione dell'intero set di numeri nel processo di raggruppamento, che non è fattibile nel caso di numeri in virgola mobile, sto ponendo la domanda seguente.

Considera un elenco di misurazioni {x,y}di alcuni tipi, dove xè un numero in virgola mobile positivo, in aumento monotono, ad esempio:

list = {{1.1,2},{2.3,4},{4.5,5},{6.2,7},{8.3,8},{9.5,8}};

abbiamo anche un elenco di confini nello xspazio tra i quali vorremmo raggruppare le letturelist

boundaries = {1,5,7,10};

Questo particolare elenco di boundariesci dice che vorremmo raggruppare le misurazioni in valori listfor xtra 1e 5, tra 5e 7e tra 7e 10. Mi piacerebbe avere una funzione groupche faccia questo:

group[list,boundaries]

{{{1.1,2}, {2.3,4}, {4.5,5}}, {{6.2,7}}, {{8.3,8}, {9.5,8}}}

Mathematica ha una funzione del genere groupo forse è possibile implementarla in modo efficiente? Naturalmente, potrei hackerare insieme un ciclo super brutto che itererebbe attraverso ogni elemento e aggiungerebbe elementi in modo appropriato, tuttavia, mi chiedo se esiste una soluzione migliore e più efficiente che si potrebbe ottenere attraverso funzioni di Mathematica più intelligenti?

Risposte

5 kglr Aug 24 2020 at 02:17

1. BinLists

grouP = Join @@ BinLists[#, {#2}, {{-∞, ∞}}] &;

grouP[list, boundaries]
 {{{1.1, 2}, {2.3, 4}, {4.5, 5}}, {{6.2, 7}}, {{8.3, 8}, {9.5, 8}}}

2. GatherBy

grouP2 = GatherBy[SortBy[First]@#, Function[x, Total[UnitStep[x[[1]] - #2]]]] &;

grouP2[list, boundaries]
 {{{1.1, 2}, {2.3, 4}, {4.5, 5}}, {{6.2, 7}}, {{8.3, 8}, {9.5, 8}}}

3. SplitBy

grouP3 = SplitBy[SortBy[First]@#, Function[x, Total[UnitStep[x[[1]] - #2]]]] &;

grouP3[list, boundaries]
 {{{1.1, 2}, {2.3, 4}, {4.5, 5}}, {{6.2, 7}}, {{8.3, 8}, {9.5, 8}}}

4. GroupBy

grouP4 = Values @ GroupBy[SortBy[First]@#, 
     Function[x, Total[UnitStep[x[[1]] - #2]]]] &;

grouP4[list, boundaries]
 {{{1.1, 2}, {2.3, 4}, {4.5, 5}}, {{6.2, 7}}, {{8.3, 8}, {9.5, 8}}}