インデックス 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 = 1000
2 つのアプローチを使用すると、次のようになります。
- アプローチ 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秒