我试图解决这个问题,但我无法实现。 你可以帮我什么吗?
问题
Mat1 | Mat2 | Mat3
1 2 | 1 3 | 2 6
1 3 | 2 6 | 2 5
2 4 | 3 1 | 3 1
3 1 | 3 5 | 5 2
4 5 |
如果有3个矩阵(例如上面),我想以[column1 column2 matrixnumber]
形式获得交叉行的结果。
以上示例的结果将是
1 3 1
1 3 2
2 6 2
2 6 3
3 1 1
3 1 2
3 1 3
如果结果的格式为[column1 column2 firstmatrix secondmatrix, ...]
1 3 1 2
2 6 2 3
3 1 1 2 3
对于这个问题,我想最多使用一个for循环。
你对此有什么想法吗?
答案 0 :(得分:4)
这里有一个替代解决方案(似乎比Gunther的运行速度快)使用MATLAB的intersect
:
Mat = {[1 2; 1 3; 2 4; 3 1; 4 5],
[1 3; 2 6; 3 1; 3 5],
[2 6; 2 5; 3 1; 5 2]};
result = zeros(sum(cellfun(@(x)size(x, 1), Mat)), 3); % # Preallocate memory
k = 1;
for cc = transpose(nchoosek(1:numel(Mat), 2))
x = intersect(Mat{cc}, 'rows'); % # Find intersection
y = ones(size(x, 1), 2) * diag(cc); % # Generate matrix indices
result(k:k + numel(y) - 1, :) = [[x; x], y(:)];
k = k + numel(y);
end
result(all(~result, 2), :) = []; % # Discard zero rows
result = unique(result, 'rows'); % # Discard repeated rows
矩阵result
现在应该包含唯一的交集行及其对应的矩阵索引,就像你想要的那样:
result =
1 3 1
1 3 2
2 6 2
2 6 3
3 1 1
3 1 2
3 1 3
答案 1 :(得分:3)
如果我理解正确,您有多组配对:Mat1
,Mat2
,Mat3
,... MatN
。现在,您想要找到唯一对,然后找出每个唯一对出现在哪个集合中。
如果您有大量套装,我建议您开始使用cell array来保留所有套装,让事情变得更轻松:
N = 3; % total number of data sets
Mat = cell(N,1);
Mat{1} = [1 2;
1 3;
2 4;
3 1;
4 5];
Mat{2} = [1 3;
2 6;
3 1;
3 5];
Mat{3} = [2 6;
2 5;
3 1;
5 2];
% etc.
首先让我们找到唯一的对:
uniq_pairs = unique(cat(1,Mat{:}),'rows');
M = size(uniq_pairs ,1);
然后使用ismember检查哪些集合包含哪些对:
matcontpair = false(M,N); %preallocate
for ii=1:N % unavoidable loop
matcontpair(:,ii) = ismember(uniq_pairs,Mat{ii},'rows');
end
要将此交集矩阵转换为每对的一组矩阵数,请再次循环它并将最终结果存储在单元格数组中(您不能使用数组,因为它们的大小可能不同(某些对只发现一次,其他两次,其他三次......)
pair_occurence= cell(M,1);
d=1:N;
for jj=1:M
pair_occurence{jj} = d(matcontpair(jj,:));
end
现在您有一个大小为uniq_pairs
的矩阵Mx2
包含唯一对,以及一个大小为pair_occurence
的出现单元格数组Mx1
:每个单元格对应一对包含该对存在的矩阵列表。
如果要从列表中删除仅存在于一个矩阵中的对,请使用以下命令:
% find them
lonely_pairs = cellfun(@numel,pair_occurence)<2;
% and destroy them
uniq_pairs(lonely_pairs,:) = [];
pair_occurence(lonely_pairs) = [];