我在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];
答案 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的默认值),您将获得以下执行时间。
如果double
是M
,则矩阵乘法会因为必须在矩阵乘法之前将其转换为数字类型而受到影响,而其他两个则有一点绩效改善。
这是我使用的测试代码。
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)