サブリストを含むk
リスト
が与えられた場合、A={{a1,a2,a3,...},{b1,b2,b3,...},...}
それらのサブリストをそれらのサブリストでソートしたいと思いますTotal[A[i]]
。これを効率的に行う方法はありますか?
3 に答える
SortBy
リストのリストをソートするためのさまざまな可能性については、ドキュメントを確認してください。
SortBy[A,Total]
あなたが必要なものを与えます。
編集:以下のウィザード氏のコメントとその中のリンクの説明によると、
SortBy[A,{Total}]
優れている。
多くの場合、 に基づくソートは、ベクトル化を利用できるため、 に基づくソートのOrdering
方が高速であることに注意してください。SortBy
この特定のケースでは、スピードアップはそれほど大きくありません。
In[50]:= test = RandomInteger[10,{5000000,5}];
In[54]:= (res1=SortBy[test,{Total}]);//Timing
(res2 = test[[Ordering[Total[test,{2}]]]]);//Timing
res1===res2
Out[54]= {1.422,Null}
Out[55]= {1.125,Null}
Out[56]= True
しかし、これはTotal
組み込み関数であるためです。導入された全体的な理由SortBy
は、効率です (つまり、単一の比較関数の場合。タイブレーカーとしての複数の比較関数の場合も便利です)。Sort
の方がより具体的であり、メインの評価シーケンスでより多くのステップをバイパスするため、より効率的です。ただし、並べ替えの基になっている関数の可能なリスト可能性 (ベクトル化された性質) を活用する方法はありません。SortBy
これは、リスト要素に 1 つずつ適用されます。注文を伴うソリューションは、並べ替え関数のホールセール計算の可能性を明示的に活用する (この場合Total[#,{2}]&
はこれを行う) ため、より高速です。
たとえば、タスクが各サブリストの 2 番目、3 番目、4 番目の要素の合計に従って並べ替える場合、パフォーマンスの差が大きくなります。
In[60]:= (res3=SortBy[test,{Total[#[[2;;4]]]&}]);//Timing
(res4=test[[Ordering[Total[test[[All,2;;4]],{2}]]]]);//Timing
res3==res4
Out[60]= {2.39,Null}
Out[61]= {1.11,Null}
Out[62]= True
一般に、パフォーマンスの向上は、計算量が多くベクトル化された並べ替え関数で最大になり、リスト全体に適用するとはるかに高速になります。ただし、並べ替えのパフォーマンス向上は、大きなリストの場合、並べ替え関数自体ほど大きくないことに注意してください。これはソートの固有の複雑さによるものでn*Log[n]
、長さの大きなリストに比例しますn
。この複雑さは常に存在します。
以下は機能するはずです(しかし、今はテストできません):
Sort[A, Total[#1]<Total[#2]&]