此问题的目标:
我正在寻找一个不考虑矩阵N
和M
的列顺序的代码。所以我尝试在下面的代码中替换以下行:
X = X1(abs(N(4,:)-N(5,:))>0.24*abs(N(5,:)));
结果X
取决于N
和M
问题:
如果M(4,:)
N(1:3,i), i=1,2,3,4,5
对应X
的所有值放在单元格abs(N(4,i)-N(5,i)) > 0.24*abs(N(5,i))
的一个向量中
N(1:3,:)
由M(1:3,:)
N(4:5,:)
用于查找X
添加实体A
以显示M
。
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];
A = [1007 4044 5002 622 1007
552 300 431 124 11
2010 1113 1100 88 20
12 25 2 32 12
15 12 10 12 7
30 55
7 ]
N = [622 1007 1007 4044 5002;
124 11 552 300 431;
88 20 2010 1113 1100;
2 4 -1.1 2.1 -3;
2.01 1 -1 2 -5];
[~,~,idx] = unique(M(1:3,:)','rows','stable')
%// Accumulate elements from the fourth row of M based on the IDs
X1 = accumarray(idx(:),M(4,:).',[],@(x) {x});
%// Use mask corresponding to abs(N(4,i)-N(5,i))>0.24*N(5,i) and
%// filter out some of the cells from the output
X = X1(abs(N(4,:)-N(5,:))>0.24*abs(N(5,:)));
我的例子:
如果N
和M
正确排序:
X = {[12,7],[2 10 55]}
[12 7]
对应N(1:3,2)
,abs(N(4,2)-N(5,2))>0.24*abs(N(5,2))
[2 10 55]
对应N(1:3,5)
,abs(N(4,5)-N(5,5))>0.24*abs(N(5,5))
可能的解决方案:(使用我的真实数据提供正确的结果)
for i = 1:size(N,2)
N(6,i) = i;
end
for h = 1:size(M,2)
for l = 1:size(N,2)
if M(1:3,h) == N(1:3,l)
M(5,h) = N(6,l);
end
end
end
p = 0;
for i = 1:size(N,2)
if abs(N(4,i)-N(5,i))>0.24*abs(N(5,i))
Mint = M(:,ismember(M(5,:).',i.', 'rows').');
p = p+1;
X{1,p} = Mint(4,:);
end
end
答案 0 :(得分:1)
看看这是否适合你 -
%// Inputs
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];
N = [622 1077 1007 4044 5002;
124 11 552 300 431;
88 20 2010 1113 1100;
2 4 -1.1 2.1 -3;
2.01 1 -1 2 -5];
[unqrows,~,idx] = unique(M(1:3,:)','rows','stable')
unqcols = unqrows.';
%// Accumulate elements from the fourth row of M based on the IDs
X1 = accumarray(idx(:),M(4,:).',[],@(x) {x}); %//'
%// "Regularize" X1 %//'
[~,sort_idx] = sortrows(unqcols.'); %//'
X1_sorted = X1(sort_idx);
%// Use mask corresponding to abs(N(4,i)-N(5,i))>0.24*N(5,i) and
%// filter out some of the cells from the output
X = X1_sorted(abs(N(4,:)-N(5,:))>0.24*abs(N(5,:)));
%// Sort, keep unique elements and make them row vectors
%// within each cell of X (if needed)
X = cellfun(@(x) unique(x).',X,'Uni',0);
输出 -
>> celldisp(X)
X{1} =
7 12
X{2} =
2 10 55
答案 1 :(得分:1)
使用逻辑索引可以显着加快脚本速度。 MATLAB在for循环方面表现不佳。请尝试以下代码:
k = size(N,2);
r = size(M,2);
M(5:7,:) = 0;
for ii = 1:k
index = sum(M(1:3,:) == repmat(N(1:3,ii),1,r),1)>2;
M(5,index) = ii;
M(6,index) = N(4,ii);
M(7,index) = N(5,ii);
end
filter = abs(M(6,:)-M(7,:))>0.24*abs(M(7,:));
X = {};
for ii = 1:k
X = [X, M(4,M(5,:) == ii& filter)];
end
在我的计算机上,执行代码需要0.017825秒。我花了0.002780秒。我会说这有一些改进。如果您想进行更详细的比较,请使用profile。
答案 2 :(得分:1)
ismember
是解决问题的好方法。它告诉您一个矩阵的元素(或行)何时出现在第二个矩阵中,并且比使用循环的方法快得多。此代码与您发布的较大数据集上的解决方案相匹配:
isGood = abs(N(4,:)-N(5,:))>0.24*abs(N(5,:));
[junk, inds] = ismember(M(1:3, :)', N(1:3, isGood)', 'rows');
X = cell(1, sum(isGood));
for i = 1:sum(isGood)
X{i} = M(4, inds==i);
end