我有一个索引数组I和值X,并且想要生成一个单元格数组C,因此C {i} = X(I == i).计算C的最快和最好的方法是什么?
最直接的方法是为I中的所有唯一i(方法1)评估C {i} = X(I == i):
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时,两种方法采用:
>方法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秒