2015-09-14 20 views
11

Ho due Vec s che corrispondono a un elenco di vettori di funzionalità e le relative etichette di classe corrispondenti e vorrei raggrupparli in base alle etichette di classe.Come posso co-ordinare due Vec in base ai valori in uno dei Vec?

Tuttavia, Rust's sort_by opera su una sezione anziché essere una funzione generica su un tratto (o simile), e la chiusura ottiene solo gli elementi da confrontare piuttosto che gli indici in modo che io possa hackerare di nascosto l'ordinamento per essere parallelo .

Ho considerato la soluzione:

let mut both = data.iter().zip(labels.iter()).collect(); 
both.sort_by(blah blah); 
// Now split them back into two vectors 

Preferirei non allocare un nuovo vettore di farlo ogni volta perché la dimensione dei dati può essere estremamente grande.

Posso sempre implementare il mio tipo, ovviamente, ma se c'è un modo incorporato per farlo sarebbe molto meglio.

+0

Suppongo che ci sia una buona ragione per non avere un vettore di strutture in cui ogni struttura contiene una caratteristica e una classe? – Shepmaster

+0

@Shepmaster Lo sto passando in libsvm che richiede che siano separati, quindi sfortunatamente sì. – LinearZoetrope

+4

Un modo per minimizzare le allocazioni è di allocare solo un vettore di indici (se avrai meno di 4 miliardi di elementi, devono solo essere 'u32', quindi 4 byte per elem.) E ordinarli tramite' sort_by' indicizzazione in 'labels'. Il risultato può quindi essere usato per permutare 'data' e' labels' nell'ordine corretto. (Sfortunatamente alloca ancora la memoria O (n), ovviamente.) – huon

risposta

2

Ho appena scritto a crate "permutation" che ti permette di fare questo :)

let names = vec!["Bob", "Steve", "Jane"]; 
let salary = vec![10, 5, 15]; 
let permutation = permutation::sort(&salary[..]); 
let ordered_names = permutation.apply_slice(&names[..]); 
let ordered_salaries = permutation.apply_slice(&salary[..]); 
assert!(ordered_names == vec!["Steve", "Bob", "Jane"]); 
assert!(ordered_salaries == vec![5, 10, 15]); 

E 'probabile che sosterrà questo in una sola chiamata di funzione in futuro.

+3

Grazie per aver contribuito alla community di Rust.Per i miei scopi, è un peccato che questo sia concesso sotto licenza GPL e non MIT/Apache, come la maggior parte delle librerie Rust. – Shepmaster

+1

Ho aggiornato la licenza per avere una doppia licenza con Apache/MIT, come Rust. –

Problemi correlati