我在Matlab中有一个矩阵D
。它是由3行组成的4个矩阵的串联(为清晰起见,添加了断点)。我想确定总矩阵中唯一行的数量,并列出每个子矩阵的数量,并计算它们发生的次数。
D=[1 0 1 1;
0 1 1 1;
1 1 0 1;
--------
1 1 0 1;
1 1 0 1;
0 1 1 1;
--------
1 1 1 0;
0 1 1 1;
1 0 1 1;
--------
1 0 1 1;
1 0 1 1;
1 1 0 0]
因此对于上面的矩阵,有5个唯一的行:
1 0 1 1
0 1 1 1
1 1 0 1
1 1 1 0
1 1 0 0
所以将这5行划分为4个子矩阵,其中出现的计数为:
C=[1 0 1 1 1;
0 1 1 1 1;
1 1 0 1 1;
1 1 1 0 0;
1 1 0 0 0;
--------
1 0 1 1 0;
0 1 1 1 1;
1 1 0 1 2;
1 1 1 0 0;
1 1 0 0 0;
----------
1 0 1 1 1;
0 1 1 1 1;
1 1 0 1 0;
1 1 1 0 1;
1 1 0 0 0;
----------
1 0 1 1 2;
0 1 1 1 0;
1 1 0 1 0;
1 1 1 0 0;
1 1 0 0 1]
答案 0 :(得分:3)
<强>代码强>
%// Cut into a 3D array after every n rows
mat3d = permute(reshape(D,n,size(D,1)/n,[]),[1 3 2])
%// Get unique rows
unqmat = unique(D,'rows','stable')
%// Find equalities
eqs = bsxfun(@eq,mat3d,permute(unqmat,[4 2 3 1]))
%// Get counts
counts = squeeze(sum(all(eqs,2),1)).' %//'
%// Restructure to get the desired output
C = [repmat(unqmat,[m 1]) counts(:)]
似乎较旧的MATLAB版本没有 unique(..'rows','stable')
功能来保持行顺序。同样,这里也是一个经过测试的建议替代品 -
function out = unique_rows_stable(A)
[unqmat_notinorder,row_ind] = unique(A,'rows');
[~,ordered_rowind] = sort(row_ind);
out = unqmat_notinorder(ordered_rowind,:);
return;
因此,可以编辑早期的解决方案代码以改为unqmat = unique_rows_stable(D)
。
答案 1 :(得分:2)
如果D
仅包含0和1:您可以将每行解释为二进制数,然后使用accumarray
计算出现次数,如下所示:
nr = 3; %// number of rows of each submatrix
Db = bin2dec(char(D+'0'))+1; %// convert each row into a binary number, plus 1
R = accumarray([Db ceil(1/nr:1/nr:size(D,2)).'], 1, [], [], [], true); %'// count
%// occurrences. Sparse to save memory. Each col is a submatrix
[u v] = unique(Db,'stable'); %// unique values
R = reshape(R(u,:), [], 1); %// get only results for values that are present
C = [repmat(D(v,:), size(D,1)/nr, 1) full(R)]; %// build result
答案 2 :(得分:1)
仅供参考,这样的问题通常会被关闭,因为它无法解释您尝试过的内容以及您实际遇到的问题。我只是觉得这听起来像是一个有趣的练习,而且我还没有用Matlab编写一段时间,所以我想我会试一试。希望它有所帮助!
D=[1 0 1 1;
0 1 1 1;
1 1 0 1;
1 1 0 1;
1 1 0 1;
0 1 1 1;
1 1 1 0;
0 1 1 1;
1 0 1 1;
1 0 1 1;
1 0 1 1;
1 1 0 0]
rows = [];
for i = 1:length(D)
skip = 0;
for j = 1:size(rows,1)
if all(rows(j,:) == D(i,:))
skip = 1;
end
end
if ~skip
rows = [rows; D(i,:)];
end
end
C = [];
for i = 1:4
for j = 1:length(rows)
count = 0;
for k = 1:3
if all(D((i-1)*3+k,:) == rows(j,:))
count = count + 1;
end
end
C = [C; [rows(j,:) count]];
end
end
C