4

インデックス I と値 X の配列があり、C{i} = X(I==i) となるセル配列 C を作成したいと考えています。C を計算するための最速かつ最良の方法は何ですか?

最も簡単な方法はC{i} = X(I==i)、I 内のすべての一意の i を評価することです (アプローチ 1)。

for i = unique(I)
    C{i} = X(I == i);
end

別の素朴なアプローチは、I のすべての i をループし、対応する x を C に追加することです (アプローチ 2)。

C = cellfun(@(x)(zeros(1,0)),cell(1,max(indices)),'UniformOutput',false);
for j = 1:length(I)
    i = I(j);
    C{i} = cat(2,C{i},X(j));
end

どちらのアプローチも非常に高速ではありません。ベンチマークを行うために、いくつかのテスト データを生成しましょう。

I = floor(rand(1,N)*M)+1;
X = rand(1,N);

N = 1000000, M = 10002 つのアプローチを使用すると、次のようになります。

  • アプローチ 1: 4.79 秒
  • アプローチ 2: 11.1 秒

ここでは、アプローチ 1 が最適です (それでも非常に遅い)。問題のパラメータを次のように変更すると、N = 1000000, M = 10000状況が大幅に変わります。

  • アプローチ 1: 48.5 秒
  • アプローチ 2: 10.3 秒

基本的に、どちらのアプローチも桁違いに遅すぎます。Cを評価する最良の方法は何ですか?

編集:正解は明らかにJonasの以下です。参考までにベンチマーク結果を添付します。上記の方法と比較すると、C の要素の順序は異なります。それとは別に、以下は同じ出力を提供します:

C = accumarray(I',X,[],@(x){x'})';
  • N = 100000, M = 1000:0.0397秒
  • N = 100000, M = 10000:0.145秒
4

1 に答える 1

5

最速の書き込み方法 (そしておそらく最速の実行方法) は次のとおりです。accumarray

C = accumarray(I,X,[],@(x){x});
于 2013-03-23T15:24:43.213 に答える