在矩阵的每一行中查找1的列索引

时间:2016-03-11 22:15:17

标签: matlab matrix

我在Matlab中有以下矩阵:

M = [0 0 1
     1 0 0
     0 1 0
     1 0 0
     0 0 1];

每行只有一个1.我如何(没有循环)确定列向量,以便第一个元素是2,如果第二列中有1,则第二个元素是3,表示第三栏等?上面的例子应该变成:

M = [ 3
      1
      2
      1
      3];

3 个答案:

答案 0 :(得分:5)

你可以用简单的矩阵乘法来解决这个问题。

result = M * (1:size(M, 2)).';

     3
     1
     2
     1
     3

这可以通过将M x 3矩阵与3 x 1数组相乘来实现,其中3x1的元素只是[1; 2; 3]。简而言之,对于M的每一行,使用3 x 1阵列执行逐元素乘法。只有M行中的1个才会在结果中产生任何结果。然后将该元素乘法的结果相加。因为你只有一个" 1"每行,结果将是1所在的列索引。

例如,对于M的第一行。

element_wise_multiplication = [0 0 1] .* [1 2 3]

    [0, 0, 3]

sum(element_wise_multiplication)

    3

<强>更新

根据以下@reyryeng@Luis提供的解决方案,我决定进行比较,看看各种方法的效果如何比较。

要设置测试矩阵(M),我创建了一个原始问题中指定形式的矩阵,并改变了行数。使用randi([1 nCols], size(M, 1))随机选择哪一列具有1。使用timeit分析执行时间。

使用类型为M的{​​{1}}运行时(MATLAB的默认值),您将获得以下执行时间。

enter image description here

如果doubleM,则矩阵乘法会因为必须在矩阵乘法之前将其转换为数字类型而受到影响,而其他两个则有一点绩效改善。

enter image description here

这是我使用的测试代码。

logical

答案 1 :(得分:2)

您还可以滥用find并观察M转置的位置。您必须首先转置矩阵,因为find按列主要顺序运行:

M = [0 0 1
     1 0 0
     0 1 0
     1 0 0
     0 0 1];

[out,~] = find(M.');

不确定这是否比矩阵乘法更快。

答案 2 :(得分:2)

另一种方法:使用max的第二个输出:

[~, result] = max(M.', [], 1);

或者,根据@rayryeng的建议,在第二维使用max而不是转置M

[~, result] = max(M, [], 2);

有关

M = [0 0 1
     1 0 0
     0 1 0
     1 0 0
     0 0 1];

这给出了

result =
     3     1     2     1     3

如果M在给定行中包含多个1,则会给出第一个1的索引。