如何使用逻辑索引和切片的组合在Matlab中“切割”矩阵?

时间:2013-07-22 23:12:36

标签: matlab

我有一个类似于此的矩阵M:

M = [   1, 2, 3, 0, 0;
        1, 2, 0, 0, 0;
        2, 3, 4, 5, 0;
        4, 5, 6, 0, 0;
        1, 2, 3, 4, 5;
    ]

我正在尝试使用A中每行的最右边非零值来获取列向量,但仅适用于第一列== 1的行。

我可以为行计算过滤器:

r = M( :, 1 ) == 1;
> r = [ 1; 1; 0; 0; 1 ]

我有一组指数“M中每行的最右边非零值”:

> c = [ 3, 2, 4, 3, 5 ]

如何在A的切片中组合这些以获得我正在寻找的东西?我正在寻找类似的东西:

A( r, c )
> ans = [ 3; 2; 5 ]

但出于某种原因,这样做会让我得到3x3矩阵。

5 个答案:

答案 0 :(得分:1)

我能想到的最短路径如下:

% Get the values of the last non-zero entry per row
v = M(sub2ind(size(M), 1:size(M,1), c))

% Filter out the rows that does not begin with 1.
v(r == 1)

答案 1 :(得分:1)

这似乎有效(我假设已经执行了定义r,c的其他操作):

M(sub2ind(size(A),find(r==1).',c(r==1))).'

对问题和解决方案的简短解释:

M( r, c )
由于逻辑和下标索引的混合,

给出3 x 5矩阵(根据需要不是3 x 1)。 r中的逻辑索引选择Ar==1的行。同时,行数组c根据数字索引从每行中选择元素:

ans =

     3     2     0     3     0
     0     2     0     0     0
     3     2     4     3     5

您真正想要的是以1开头的每行中最右边非零元素的索引。该解决方案使用线性索引(数字)从矩阵中获取正确的元素。

答案 2 :(得分:0)

我认为这应该可以解决问题。我想知道是否有更优雅的方式来做到这一点。

% get only rows u want, i.e. with first row == 1
M2 = M(r,:);

% get indices of
% "the rightmost non-zero value of each row in M" 
% for the rows u want 
indicesOfinterest = c(r==1);


noOfIndeciesOfinterest = numel(indicesOfinterest);

% desired output column vector
output = zeros(noOfIndeciesOfinterest, 1);

% iterate through the indeces and select element in M2
% from each row and column indicated by the indice.
for idx = 1:noOfIndeciesOfinterest
    output(idx) = M2(idx, indicesOfinterest(idx));
end

output % it is [3; 2 ; 5]

答案 3 :(得分:0)

您可以使用

arrayfun(@(x) M(x,c(x)), find(r))

但除非您出于其他目的需要rc,否则可以使用

arrayfun(@(x) M(x,find(M(x,:),1,'last')), find(M(:,1)==1))

答案 4 :(得分:0)

以下是使用线性索引的方法:

N = M';
lin_index = (0:size(N,1):prod(size(N))-1) + c;
v = N(lin_index);
v(r)