2017-10-27 8 views
2

に、私はすべてがこのソート複数のキーによって辞書の配列、ジュリア

{ 
    "id": 12345, 
    "user_id": "6789", 
    "question_id": "some_question_id", 
    "correct": "true", 
    "actions": "...", 
    "consequentiality": 0, 
    "timestamp": 1505123456.000 
} 

のように見えるDict秒の大規模な配列を持っていると私は最も遅い移動question_id(question_id, user_id, id, consequentiality)によってそれらをソートする必要がある、とconsequentiality移動グループ化やサブグループ化のような高速化は可能ですが、順序付き配列のスワップを特定のケースで実行する必要があります。これらのほとんどはグループ間で発生する傾向があります。私はbyltに異なる機能を渡して、Base.sortで遊んでいました。最高のは、私は、複数の種類に一方が他方の内側を組み合わせ、各by句、あなたが画像を取得します

sort(sort(sort(sort(df, by=x->x["question_id"]), by=x->x["user_id"] ... 

のようなものに異なるキーを渡して思い付きました。これまでは、MergeSortのような安定したアルゴリズムを使用していても、満足のいく安定した順序には達していませんでした。

ヘルプ?

EDITby節にタプルを使用するのは意味がありますか?しかし、どのように非数値要素の順序を逆にするのですか?

+1

ソート '試し(= X-> getindexによってDF、(X、( "question_id"、 "USER_ID"、 "ID"、 "consequentiality")))。 ' –

+0

数値以外の値の順序を逆にすることについては、これは' lt = 'パラメータでより小さいカスタム関数を必要とするかもしれません。 –

+0

'getindex'に関して、うまくいきます、ありがとう。タプルでキーを指定するのと同じですか? 'lt'関数に関しては、チェーンを作るのか、もっと洗練されたものが必要ですか?以前にチェーンチェーンを試したときに、私が望む相対的な順序を得ることができなかったので。 'getindex'(またはタプル?)を持つのが助けになるのでしょうか? – Morpheu5

答えて

1

コメントにlt=...を使用してソリューションをクリーンアップする方法のデモンストレーションです。これは、タプルに対してのみislessを再定義するので、タプルでのみ機能することに注意してください。熱狂があるなら、多分このような何かがJuliaかいくつかのパッケージに組み込まれるかもしれません。

julia> struct RevNext 
     end 

julia> import Base: isless 

julia> function isless(t1::Tuple, t2::Tuple) 
      n1, n2 = length(t1), length(t2) 
      reverse = false 
      for i = 1:min(n1, n2) 
       a, b = t1[i], t2[i] 
       if !isequal(a, b) 
        return reverse ? isless(b, a) : isless(a,b) 
       else 
        reverse = isa(a,RevNext) 
       end 
      end 
      return n1 < n2 
     end 
WARNING: Method definition isless(Tuple, Tuple) ... 
isless (generic function with 53 methods) 

そして、それを使用するには、sort(M,by=x->(x[:b], RevNext(), x[:a]))と書きます。ランダムに生成されたベクトルMの例:

julia> M = [Dict(:a=>rand(),:b=>rand(Bool)) for i=1:10] 
10-element Array{Dict{Symbol,Any},1}: 
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.735352),Pair{Symbol,Any}(:b, true)) 
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.537437),Pair{Symbol,Any}(:b, true)) 
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.314947),Pair{Symbol,Any}(:b, true)) 
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.9723),Pair{Symbol,Any}(:b, false)) 
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.605042),Pair{Symbol,Any}(:b, true)) 
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.256509),Pair{Symbol,Any}(:b, false)) 
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.133487),Pair{Symbol,Any}(:b, false)) 
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.320249),Pair{Symbol,Any}(:b, false)) 
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.409549),Pair{Symbol,Any}(:b, true)) 
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.421471),Pair{Symbol,Any}(:b, true)) 

julia> sort(M,by=x->(x[:b], RevNext(), x[:a])) 
10-element Array{Dict{Symbol,Any},1}: 
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.9723),Pair{Symbol,Any}(:b, false)) 
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.320249),Pair{Symbol,Any}(:b, false)) 
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.256509),Pair{Symbol,Any}(:b, false)) 
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.133487),Pair{Symbol,Any}(:b, false)) 
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.735352),Pair{Symbol,Any}(:b, true)) 
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.605042),Pair{Symbol,Any}(:b, true)) 
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.537437),Pair{Symbol,Any}(:b, true)) 
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.421471),Pair{Symbol,Any}(:b, true)) 
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.409549),Pair{Symbol,Any}(:b, true)) 
Dict{Symbol,Any}(Pair{Symbol,Any}(:a, 0.314947),Pair{Symbol,Any}(:b, true)) 
+0

私は他のソリューションよりも優れていると思います。どちらもちょっとぎこちなかったですが、もう1つはよりコンパクトで、まったく一般的ではありませんでした。少なくとも、隣接するパラメータのセマンティクスを変えるパラメータは含まれていません。もともと、私は、 'sort 'の' rev'パラメータが、 'by'で渡されたタプルを逆転させるかどうかを判断するブール値の組を受け入れることを望んでいました。 – Morpheu5

関連する問題