【发布时间】:2015-08-04 23:50:54
【问题描述】:
如何避免循环以减少这段代码的计算时间(one solution of my last question):
我希望找到A(1:3,:) 的列向量,其在M(4,:) 中的对应值不属于单元格X 的向量之一(并且显然不等于这些向量之一)。如果X 非常大,我会寻找一个快速的解决方案。
M = [1007 1007 4044 1007 4044 1007 5002 5002 5002 622 622;
552 552 300 552 300 552 431 431 431 124 124;
2010 2010 1113 2010 1113 2010 1100 1100 1100 88 88;
7 12 25 15 12 30 2 10 55 32 12];
这里我直接取A:
A = [1007 4044 5002 622;
552 300 431 124;
2010 1113 1100 88];
A 包含 M(1:3,:) 的唯一列向量
X = {[2 5 68 44],[2 10 55 9 17],[1 55 6 7 8 9],[32 12]};
[~, ~, subs] = unique(M(1:3,:)','rows');
A4 = accumarray(subs(:),M(4,:).',[],@(x) {x});
%// getting a mask of which columns we want
idxC(length(A4)) = false;
for ii = 1:length(A4)
idxC(ii) = ~any(cellfun(@(x) all(ismember(A4{ii},x)), X));
end
显示我们想要的列
out = A(:,idxC)
结果:
>> out
out =
1007 4044
552 300
2010 1113
列向量[5002;431;1100] 被删除,因为[2;10;55] 包含在X{2} = [2 10 55 9 17] 中
列向量[622;124;88] 被消除,因为[32 12] = X{4}
另一个例子:同一个X
M = [1007 4044 1007 4044 1007 5002 5002 5002 622 622 1007 1007 1007;
552 300 552 300 552 431 431 431 124 124 552 11 11;
2010 1113 2010 1113 2010 1100 1100 1100 88 88 2010 20 20;
12 25 15 12 30 2 10 55 32 12 7 12 7];
X = {[2 5 68 44],[2 10 55 9 17],[1 55 6 7 8 9],[32 12]};
A = [1007 4044 5002 622 1077;
552 300 431 124 11;
2010 1113 1100 88 20];
结果:(带有 scmg 答案)
如果A按照第一行排序得到:(正确结果)
out =
1007 1007 4044
11 552 300
20 2010 1113
如果我不对矩阵A 进行排序,我会得到:(错误结果)
out =
4044 5002 622
300 431 124
1113 1100 88
列向量A(:,4) = [622;124;88] 应该被删除,因为[32 12] = X{4}。
列向量[5002;431;1100]应该被删除,因为[2;10;55]包含在X{2} = [2 10 55 9 17]中
【问题讨论】:
-
你能解释一下你如何获得输出的逻辑吗?这将节省我们尝试从您的代码中推断出来的时间
-
@LuisMendo:我的问题收到了两个答案。 scmg 响应给出了 rignt 输出,如示例中所示,但如果 X 非常大,则需要大量计算时间。 Ben Voigt 开发的逻辑很有趣,但输出结果是错误的,我不知道为什么!我的问题中的输入是 M、A 和 X,输出是 out = A(:,idxC)
-
@LuisMendo:我希望找到 A(1:3,:) 的列向量,其 M(4,:) 中的相应值不属于单元格 X 的向量之一(显然不等于这些向量之一)。如果 X 很大,我会寻找一个快速的解决方案。
-
澄清一下:您的意思是“M(4,:) 中的对应值不是单元格 X 的 相同 向量的一部分”,对吧?
-
@LuisMendo:是的,单元格 X 的相同向量。
标签: matlab matrix runtime vectorization