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

Matlab 查找矩阵每行中1的列索引,matlab,matrix,Matlab,Matrix,我在Matlab中有以下矩阵: M = [0 0 1 1 0 0 0 1 0 1 0 0 0 0 1]; 每行正好有一个1。如何(无循环)确定列向量,使第一个元素为2如果第二列中有1,第二个元素为3表示第三列中的1等。?上面的例子应该变成: M = [ 3 1 2 1 3]; 你可以用简单的矩阵乘法来解决这个问题 result = M * (1:size(M, 2)).'; 3 1

我在Matlab中有以下矩阵:

M = [0 0 1
     1 0 0
     0 1 0
     1 0 0
     0 0 1];
每行正好有一个1。如何(无循环)确定列向量,使第一个元素为2如果第二列中有1,第二个元素为3表示第三列中的1等。?上面的例子应该变成:

M = [ 3
      1
      2
      1
      3];

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

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
更新

基于和下面提供的解决方案,我决定进行比较,看看各种方法的性能如何比较

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

使用
double
(MATLAB的默认值)类型的
M
运行时,您将获得以下执行时间

如果
M
是一个
逻辑
,那么矩阵乘法会受到影响,因为它必须在矩阵乘法之前转换为数字类型,而其他两种方法的性能有所提高

下面是我使用的测试代码

sizes = round(linspace(100, 100000, 100));
times = zeros(numel(sizes), 3);

for k = 1:numel(sizes)
    M = generateM(sizes(k));
    times(k,1) = timeit(@()M * (1:size(M, 2)).');
    M = generateM(sizes(k));
    times(k,2) = timeit(@()max(M, [], 2), 2);
    M = generateM(sizes(k));
    times(k,3) = timeit(@()find(M.'), 2);
end

figure
plot(range, times / 1000);
legend({'Multiplication', 'Max', 'Find'})
xlabel('Number of rows in M')
ylabel('Execution Time (ms)')

function M = generateM(nRows)
    M = zeros(nRows, 3);
    col = randi([1 size(M, 2)], 1, size(M, 1));
    M(sub2ind(size(M), 1:numel(col), col)) = 1;
end
您还可以滥用和观察
M
转置的位置。当
find
按列主顺序操作时,必须首先转置矩阵:

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

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

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

还有另一种方法:使用第二个输出:

或者,根据建议,沿第二维度使用
max
,而不是将
M
转置:

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

这给

result =
     3     1     2     1     3

如果
M
在给定行中包含多个
1
,这将给出第一个此类
1

的索引,非常感谢您的快速回答。这是完美的。
find
是一种罕见的情况,
[out,~]=…
out=…
@LuisMendo-aha是的,先生!干得好。我总是忘记这样使用
max
。我想知道所有方法之间的性能比较是什么。我的钱在
max
如果您没有转置矩阵并指定沿矩阵的行查看,是否会有性能差异?是否将要查看的维度指定为
2
M = [0 0 1
     1 0 0
     0 1 0
     1 0 0
     0 0 1];
result =
     3     1     2     1     3