我想从我的代码中删除嵌套的for循环? 我无法删除它们。
k = 3;
Data = rand(100,5);
m = zeros(size(Data));
N = size(Data,2); % number of features
M = size(Data,1); % number of objects
bound = zeros(N,k+1);
MAX = max(Data);
MIN = min(Data);
for ii = 1:N
bound(ii,:) = linspace(MIN(ii), MAX(ii), k+1);
end
bound(:,end) = bound(:,end)+eps;
tic;
for ii = 1:M
for jj=1:N
for kk=1:k
if bound(jj,kk)<=Data(ii,jj) && Data(ii,jj)<bound(jj,kk+1)
m(ii,jj) = kk;
end
end
end
end
答案 0 :(得分:0)
您可以取消嵌套到一定限度。
乍一看,由于jj
索引在嵌套循环中的操作中似乎是统一的,您可以替换
for ii = 1:M
for jj=1:N
for kk=1:k
if bound(jj,kk)<=Data(ii,jj) && Data(ii,jj)<bound(jj,kk+1)
m(ii,jj) = kk;
end
end
end
end
简单地
for ii = 1:M
for kk=1:k
m(ii,(bound(:,kk)<=Data(ii,:)' & Data(ii,:)'<bound(:,kk+1))) = kk;
end
end
这会给你与以前完全相同的结果。
答案 1 :(得分:0)
由于你的最长循环超过ii=1:M
,我们应该优先考虑将这个循环引导到其他循环。最小的循环超过kk=1:k
,所以这个可以保持不用担心它太多。您可以使用bsxfun
在此类矢量化中产生很好的效果:
for kk = 1:k
ind = bsxfun(@le, bound(:, kk)', Data) & bsxfun(@gt, bound(:, kk+1)', Data);
m(ind) = kk;
end
这与上面的代码结果相同。
答案 2 :(得分:0)
另一个替代方案是histc()
,专门用于分箱:
for jj = 1:N
[~, m(:,jj)] = histc(Data(:,jj),bound(jj,:));
end
此解决方案与bsxfun()
相同,但它不是一个非常有意义的比较,因为这里的循环是跨列,而bsxfun跨越边界。因此,根据经验,如果我的列少于边界,我将使用histc()
,否则bsxfun()
。