matlab 如何根据索引,matlab – 通过索引对值进行分组的快速方法是什么?

我有一个索引数组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秒

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值