查找矩阵条目中重复值的列索引

问题描述 投票:0回答:1

我正在使用 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
matlab matrix vectorization
1个回答
0
投票

您可以使用

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
© www.soinside.com 2019 - 2024. All rights reserved.