2017-07-26 92 views
3

我試圖將一個自定義的排序算法應用到一堆子數據框中以便繪製一些圖。隨着this question的幫助下,我能到我的數據框使用自定義排序順序:爲SubDataFrame自定義排序

julia> using DataFrames 

julia> df = DataFrame(x = rand(10), y = rand([:low, :med, :high], 10), z = rand([:a, :b], 10)) 
10×3 DataFrames.DataFrame 
│ Row │ x   │ y │ z │ 
├─────┼───────────┼──────┼───┤ 
│ 1 │ 0.436891 │ low │ b │ 
│ 2 │ 0.370725 │ high │ b │ 
│ 3 │ 0.521269 │ low │ b │ 
│ 4 │ 0.071102 │ high │ a │ 
│ 5 │ 0.969407 │ high │ a │ 
│ 6 │ 0.0416023 │ med │ b │ 
│ 7 │ 0.63486 │ med │ b │ 
│ 8 │ 0.4352 │ high │ b │ 
│ 9 │ 0.626739 │ low │ b │ 
│ 10 │ 0.151149 │ low │ a │ 

julia> o = [:low, :med, :high] 
3-element Array{Symbol,1}: 
:low 
:med 
:high 

julia> custom_sort(x,y) = findfirst(o, x) < findfirst(o, y) 
custom_sort (generic function with 1 method) 

julia> sort!(df, cols=[:y], lt=custom_sort) 
10×3 DataFrames.DataFrame 
│ Row │ x   │ y │ z │ 
├─────┼───────────┼──────┼───┤ 
│ 1 │ 0.436891 │ low │ b │ 
│ 2 │ 0.521269 │ low │ b │ 
│ 3 │ 0.626739 │ low │ b │ 
│ 4 │ 0.151149 │ low │ a │ 
│ 5 │ 0.0416023 │ med │ b │ 
│ 6 │ 0.63486 │ med │ b │ 
│ 7 │ 0.370725 │ high │ b │ 
│ 8 │ 0.071102 │ high │ a │ 
│ 9 │ 0.969407 │ high │ a │ 
│ 10 │ 0.4352 │ high │ b │ 

和它的偉大工程。麻煩的是,當我再做groupby(),自定義排序丟失:

julia> groupby(df, [:y, :z]) 
DataFrames.GroupedDataFrame 5 groups with keys: Symbol[:y, :z] 
First Group: 
2×3 DataFrames.SubDataFrame{Array{Int64,1}} 
│ Row │ x  │ y │ z │ 
├─────┼──────────┼──────┼───┤ 
│ 1 │ 0.071102 │ high │ a │ 
│ 2 │ 0.969407 │ high │ a │ 
⋮ 
Last Group: 
2×3 DataFrames.SubDataFrame{Array{Int64,1}} 
│ Row │ x   │ y │ z │ 
├─────┼───────────┼─────┼───┤ 
│ 1 │ 0.0416023 │ med │ b │ 
│ 2 │ 0.63486 │ med │ b │ 

有沒有一種方法我可以SubDataFrame有幾分使得例如。第一組是y == :lowz == a

回答

2

groupby利用PooledArray機制將DataFrame分成組。當從矢量創建PooledArray時,順序不會保留......除非在PooledArray構造函數中指定。通過將列按照所需的順序放入PooledArrays中,可以欺騙groupby。在代碼:

julia> df[:y] = PooledDataArray(df[:y],[:low,:med,:high]) 

julia> df[:z] = PooledDataArray(df[:z],[:a,:b]) 

julia> groupby(df, [:y, :z]) 
DataFrames.GroupedDataFrame 6 groups with keys: Symbol[:y, :z] 
First Group: 
1×3 DataFrames.SubDataFrame{Array{Int64,1}} 
│ Row │ x  │ y │ z │ 
├─────┼──────────┼─────┼───┤ 
│ 1 │ 0.833255 │ low │ a │ 
⋮ 
Last Group: 
1×3 DataFrames.SubDataFrame{Array{Int64,1}} 
│ Row │ x  │ y │ z │ 
├─────┼──────────┼──────┼───┤ 
│ 1 │ 0.604117 │ high │ b │ 

這也可以自動化爲多個列或列與多個值與下面的循環:

for v in [:y,:z] 
    df[v] = PooledDataArray(df[v],unique(Vector(df[v]))) 
end 

它執行相同的顯式分配早。

+0

大概我需要在使用循環創建'PooledDataArray'之前對需要它的任何列進行自定義排序? – kevbonham

+0

@kevbonham是的。實際上,似乎應該能夠根據'groupby'中所需的順序對列進行排序,並將這些列合併。之後,將數據框以不同的順序排序,然後執行「groupby」。 –

+0

太棒了,該作品了!謝謝! – kevbonham