Matlab 查找矩阵每行中1的列索引
我在Matlab中有以下矩阵: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
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