2016-06-20 38 views
5

Esiste un metodo rapido per specificare un ordine personalizzato su sort/sort! su Julia DataFrames?Ordinamento personalizzato efficiente in Julia DataFrames?

julia> using DataFrames 

julia> srand(1); 

julia> df = DataFrame(x = rand(10), y = rand([:high, :med, :low], 10)) 
10×2 DataFrames.DataFrame 
│ Row │ x   │ y │ 
├─────┼────────────┼──────┤ 
│ 1 │ 0.236033 │ med │ 
│ 2 │ 0.346517 │ high │ 
│ 3 │ 0.312707 │ high │ 
│ 4 │ 0.00790928 │ med │ 
│ 5 │ 0.488613 │ med │ 
│ 6 │ 0.210968 │ med │ 
│ 7 │ 0.951916 │ low │ 
│ 8 │ 0.999905 │ low │ 
│ 9 │ 0.251662 │ high │ 
│ 10 │ 0.986666 │ med │ 

julia> sort!(df, cols=[:y]) 
10×2 DataFrames.DataFrame 
│ Row │ x   │ y │ 
├─────┼────────────┼──────┤ 
│ 1 │ 0.346517 │ high │ 
│ 2 │ 0.312707 │ high │ 
│ 3 │ 0.251662 │ high │ 
│ 4 │ 0.951916 │ low │ 
│ 5 │ 0.999905 │ low │ 
│ 6 │ 0.236033 │ med │ 
│ 7 │ 0.00790928 │ med │ 
│ 8 │ 0.488613 │ med │ 
│ 9 │ 0.210968 │ med │ 
│ 10 │ 0.986666 │ med │ 

Mi piacerebbe avere la colonna y ordinati con :low primo, seguito da :med e :high. Quale sarebbe il modo migliore per farlo? So che posso fare quanto segue:

julia> subdfs = [] 
0-element Array{Any,1} 

julia> for val in [:low, :med, :high] 
      push!(subdfs, df[df[:y] .== val, :]) 
     end 

julia> vcat(subdfs...) 
10×2 DataFrames.DataFrame 
│ Row │ x   │ y │ 
├─────┼────────────┼──────┤ 
│ 1 │ 0.951916 │ low │ 
│ 2 │ 0.999905 │ low │ 
│ 3 │ 0.236033 │ med │ 
│ 4 │ 0.00790928 │ med │ 
│ 5 │ 0.488613 │ med │ 
│ 6 │ 0.210968 │ med │ 
│ 7 │ 0.986666 │ med │ 
│ 8 │ 0.346517 │ high │ 
│ 9 │ 0.312707 │ high │ 
│ 10 │ 0.251662 │ high │ 

C'è un modo per fare questo senza l'allocazione della memoria in quanto nel mio esempio reale, df è abbastanza grande?

risposta

4

si può definire una funzione di confronto:

lmhlt(x, y) = x == :low && y != :low || x == :med && y == :high 

Quindi utilizzare

sort!(df, lt=lmhlt) 

Tuttavia, questa alloca ancora la memoria. Tuttavia, dovrebbe essere inferiore alla versione corrente.

+1

Bello! Grazie! Ho dovuto cercare nei [docs] (http://docs.julialang.org/en/latest/stdlib/sort/) per comprendere appieno l'argomento 'lt' qui. Hanno detto: "Tutte le funzioni di ordinamento e ordine si basano su una relazione" minore di "che definisce un ordine totale sui valori da manipolare. La funzione' isless' viene invocata di default, ma la relazione può essere specificata tramite 'lt 'parola chiave." –

0

ho scritto a function to generalize custom sorting a più colonne solo specificando per ogni colonna che richiedono l'ordinamento l'ordine personalizzato:

Pkg.clone("https://github.com/sylvaticus/LAJuliaUtils.jl.git") 
using DataFrames, LAJuliaUtils 
df = DataFrame(
    c1 = ['a','b','c','a','b','c'], 
    c2 = ["aa","aa","bb","bb","cc","cc"], 
    c3 = [1,2,3,10,20,30], 
) 
customSort!(df, [(:c2,["bb","cc"]),(:c1,['b','a','c'])]) 

6×3 DataFrames.DataFrame 
│ Row │ c1 │ c2 │ c3 │ 
├─────┼─────┼──────┼────┤ 
│ 1 │ 'a' │ "bb" │ 10 │ 
│ 2 │ 'c' │ "bb" │ 3 │ 
│ 3 │ 'b' │ "cc" │ 20 │ 
│ 4 │ 'c' │ "cc" │ 30 │ 
│ 5 │ 'b' │ "aa" │ 2 │ 
│ 6 │ 'a' │ "aa" │ 1 │ 

È possibile ottenere maggiori dettagli una volta installato il pacchetto utilizzando ?customSort!

La funzione utilizza internamente il sort!() I DataFrames funzionano con la parola chiave by su uno OrderedDict basata sull'ordine personalizzato fornito dall'utente, come suggerito dall'utente Tamas_Papp su Julia Discourse.

Problemi correlati