4

我有一个类似于此的矩阵 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 矩阵。

4

5 回答 5

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)
于 2013-07-22T23:26:29.760 回答
1

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

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

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

M( r, c )

由于逻辑和下标索引的混合,给出 3 x 5 矩阵(不是所需的 3 x 1). 中的逻辑索引在 中挑出r行。同时行数组根据数字索引从每一行中挑选出元素:Ar==1c

ans =

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

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

于 2013-07-22T23:49:43.643 回答
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]
于 2013-07-22T23:42:43.460 回答
0

您可以使用

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

但除非你需要rc其他目的,你可以使用

arrayfun(@(x) M(x,find(M(x,:),1,'last')), find(M(:,1)==1))
于 2013-07-23T00:19:58.450 回答
0

这是一种使用线性索引的方法:

N = M';
lin_index = (0:size(N,1):prod(size(N))-1) + c;
v = N(lin_index);
v(r)
于 2013-07-23T08:20:16.393 回答