我使用Matlab生成了一个X-by-10数字数组。这个数组是“精神上”分为4,3和3列。如果这个数组在下面给出,则为两行
[1 2 3 4 ; 5 6 7 ; 8 9 10]
[1 2 3 4 ; 8 9 10 ; 5 6 7]
分号是精神分裂。我将需要进一步处理这个数组,但'mental column'排列提供相同的信息。第二行是第一行的第二和第三个“心理行”的排列。
有没有简单的方法可以摆脱Matlab内置函数的排列?类似于识别排列的唯一。
答案 0 :(得分:2)
假设您的行存储在矩阵A
中,并且列集宽度存储在len
中(在您的情况下为len = [4, 3, 3]
)。首先,我们应该在单元格数组中正确表示这些数据:
X = mat2cell(A, ones(size(A, 1), 1), len);
然后我们在这样的单元格数组中找到所有可能的列组合(不重复):
cols = perms(1:numel(len));
现在,对于来自X
的指定r1
和r2
的两行,我们会检查一行是否是另一行的排列(即重新排序“心理“专栏”:
any(arrayfun(@(n)isequal(X(r1, :), X(r2, cols(n, :))), 1:size(cols, 1)))
在此之后,我们现在可以找到所有可能的行对(不重复),并且对于每对行检查它们是否是彼此的排列:
rows = nchoosek(1:size(A, 1), 2);
N = size(cols, 1);
isperm = @(ii, jj)any(arrayfun(@(n)isequal(X(ii, :), X(jj, cols(n, :))), 1:N));
remove_idx = arrayfun(isperm, rows(:, 1), rows(:, 2));
删除它们就像馅饼一样简单:
A(remove_idx, :) = [];
我们将以下数据作为输入:
A = [1:10; 11:20; 1:4 8:10 5:7];
len = [4 3 3];
那是:
A =
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
1 2 3 4 8 9 10 5 6 7
len =
4 3 3
并运行以下代码:
X = mat2cell(A, ones(size(A, 1), 1), len);
cols = perms(1:numel(len))
rows = nchoosek(1:size(A, 1), 2)
N = size(cols, 1)
isperm = @(ii, jj)any(arrayfun(@(n)isequal(X(ii, :), X(jj, cols(n, :))), 1:N));
remove_idx = arrayfun(isperm, rows(:, 1), rows(:, 2));
A(remove_idx, :) = [];
结果是:
remove_idx =
0
1
0
A =
1 2 3 4 5 6 7 8 9 10
1 2 3 4 8 9 10 5 6 7
答案 1 :(得分:0)
这比将数字转换为数字序列要好得多。但它是相同的想法,即将数字组映射到唯一标识符。这是我的代码。
M=[1 2 3 4 5 6 7 8 9 10;1 2 3 4 8 9 10 5 6 7;5 6 7 8 9 10 11 1 2 3;5 6 7 8 1 2 3 9 10 11];
%chop matrix into mental columns
M4=M(:,1:4);
M3=[M(:,5:7);M(:,8:10)]; % stack the 3s together
[u_M4,ia_M4,ic_M4]=unique(M4,'rows');% give each unique row of 4 a one digit id
[u_M3,ia_M3,ic_M3]=unique(M3,'rows');% give each unique row of 3 a one digit id
idx3=[ic_M3(1:length(ic_M3)/2) ic_M3(length(ic_M3)/2+1:end)]; % reshape the ids for the 3 so it matches the original format
sort_idx3=sort(idx3,2); % sort
idx=[ic_M4 sort_idx3]; % construct the idx matrix consist of the one digit ids
[u_idx,ia_idx,ic_idx]=unique(idx,'rows'); %find of unique id ROWs (that's why we need to sort before)
R=M(ia_idx,:); % now filter the original matrix