如何在不使用for循环的情况下实现此Matlab代码?
b=10:10:50
a=50*rand(1,50);
for ii=2:numel(b)
ind{ii}=find(a<b(ii) & a>b(ii-1));
end
答案 0 :(得分:3)
看起来你正在做直方图并跟踪哪个元素最终在哪个bin中。这意味着你可以通过以下几行“几乎”得到你想要的东西:
a = 50 * rand(1, 50);
b = 10:10:50;
[h c] = histc(a, b);
现在c包含a中每个元素的“bin”的索引。例如,如果
a = [15 22 9 7 25];
然后
c = [1 2 0 0 2];
不确定将这些收集到单元格数组中的价值 - 在我看来,ind
中的值可以用c
来完成。
我怀疑用“向量”操作创建一个单元格数组(可能有不同长度)可能很难(这意味着长度相同的东西)...有兴趣看到有人产生反例!
编辑:我发现了我自己的反例...以下行生成了一个单元数组ind
就像你的代码一样(arrayfun
命令确实有一个隐含的for
循环但是被认为是“矢量化”)。
ind = arrayfun(@(x)find(x==c),1:numel(b)-1, 'uniformoutput', false);
注意,完成此操作后,单元格数组ind
的值将从单元格ind{1}
开始,而原始代码则从单元格ind{2}
索引。如果这是一个问题,我相信你可以解决它......
另请注意,您的代码会在0
和50
之间生成随机数,但您的“有效容器”仅在10
和50
之间(因为您的方式)写了你的算法)。因此,收集的指数总和将略低于50(平均为40)。
答案 1 :(得分:2)
下面的脚本会做同样的事情。矩阵newInd
将包含分配给ind
的相同值,并由循环打印出来。
b=10:10:50;
a=sort(randi(50,1,10));
% create shifted version of vector b to account
% for comparison between i and i-1
newB1 = b(1:end-1);
newB2 = b(2:end);
% create tiled version of a and b
newB1 = repmat(newB1',1,numel(a));
newB2 = repmat(newB2',1,numel(a));
newA = repmat(a,numel(b)-1,1);
%find linear indices that meet required conditions
LinearInd = find(newA<newB2 & newA>newB1);
%convert linear indices to subscripts
[i,newInd] = ind2sub(size(newA),LinearInd);
% display indices that correspond to ind
newInd