我正在使用 Matlab 表示法。 我有一个大小为 (Nx3) 的矩阵 A,其中 A 的每个条目都是正整数。我想创建一个维度为 (max(max(A))x2) 的矩阵 Q。 Q 的行 i 对应于 A 的列索引,因此 A(k,r) = i。 因此,如果 A(k_1,r_1) = i 且 A(k_2,r_2) = i,我们可以设置 Q(i,:)=[k_1,k_2]。 对于 A 的唯一条目,Q 的关联行的每一列都相等。
有没有办法将任务矢量化? 我可以使用循环执行该任务,但在 MATLAB 中效率非常低(当矩阵 A 有很大的行并且 max(max(A)) 也很大时)。这是一个例子。
A=[ 1 10 9
1 2 4
3 2 11
3 12 5
6 13 4
6 7 15
8 7 5
8 14 16]
在上面的例子中,预期的结果是
Q =
1 1
2 2
1 1
3 3
3 3
1 1
2 2
1 1
3 3
2 2
3 3
2 2
2 2
2 2
3 3
3 3
这就是我的慢速代码所做的事情
max_Q = max(max(A));
Q = zeros(max_Q,2);
for i = 1 : max_Q
[~,cols] = find(i == A);
Q(i,:) = cols;
end
您可以使用
unique
返回的线性索引来给出每个唯一整数的列号。由于默认情况下整数按排序顺序给出,因此索引列表(转换为列号)给出输出的一列。
鉴于:
A=[ 1 10 9
1 2 4
3 2 11
3 12 5
6 13 4
6 7 15
8 7 5
8 14 16]
找到每个整数第一次出现的索引:
[Y,I] = unique(A); % Y is not necessary, only there for verification
disp([Y,I]);
1 1
2 10
3 3
4 18
5 20
6 5
7 14
8 7
9 17
10 9
11 19
12 12
13 13
14 16
15 22
16 24
然后可以使用
ind2sub
: 将线性索引转换为(行和)列数
[~,C] = ind2sub(size(A),I)
C =
1
2
1
3
3
1
2
1
3
2
3
2
2
2
3
3
如果保证两次出现的整数都在同一列中,我们就完成了:
Q = [C, C];
如果整数出现在不同列中,我们将再次使用
unique
:
B = A;
B(4,[2,3]) = B(4,[3,2])
B =
1 10 9
1 2 4
3 2 11
3 5 12
6 13 4
6 7 15
8 7 5
8 14 16
[~,I] = unique(B, "first");
[~,C] = ind2sub(size(B),I);
Q(:,1) = C;
[~,I] = unique(B, "last");
[~,C] = ind2sub(size(B),I);
Q(:,2) = C;
disp(Q);
1 1
2 2
1 1
3 3
2 3
1 1
2 2
1 1
3 3
2 2
3 3
3 3
2 2
2 2
3 3
3 3