简体   繁体   English

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

[英]How to “chop up” matrix in Matlab using combination of logical indexing and slicing?

I have a matrix M that looks similar to this: 我有一个看起来像这样的矩阵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;
    ]

I'm trying to get a column vector with the rightmost non-zero value of each row in A, but ONLY for the rows that have the first column == 1. 我正在尝试获取具有A中每一行的最右非零值的列向量,但仅适用于具有第一列== 1的行。

I'm able to calculate a filter for the rows: 我能够为行计算过滤器:

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

And I have a set of indices for "the rightmost non-zero value of each row in M": 我有一组索引“ M中每行的最右边非零值”:

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

How do I combine these in a slicing of A in order to get what I'm looking for? 如何将它们组合成A切片以获取所需的内容? I'm looking for something like: 我正在寻找类似的东西:

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

But doing this gets me a 3x3 matrix, for some reason. 但是出于某种原因,这样做会使我得到3x3矩阵。

The shortest way I can think of is as follows: 我能想到的最短的方法如下:

% 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)

This seems to work (I assume other operations defining r,c have been performed): 这似乎可行(我假设已经执行了定义r,c其他操作):

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

Short interpretation of the problem and solution: 问题和解决方案的简短解释:

M( r, c )

gives a 3 x 5 matrix (not 3 x 1 as desired) due to mixing of logical and subscript indices. 由于逻辑索引和下标索引的混合,给出了一个3 x 5的矩阵(不是所需的3 x 1)。 The logical indices in r pick out rows in A with r==1 . r的逻辑索引选择Ar==1 Meanwhile row array c picks out elements from each row according to the numeric index: 同时,行数组c根据数字索引从每一行中选择元素:

ans =

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

What you really want are indices into the rightmost nonzero elements in each row starting with 1 . 您真正想要的是从1开始的每行中最右边的非零元素的索引。 The solution uses linear indices (numeric) to get the correct elements from the matrix. 该解决方案使用线性索引(数字)从矩阵中获取正确的元素。

I think this should do the trick. 我认为这应该可以解决问题。 I wonder if there is more elegant way of doing this though. 我不知道是否有更优雅的方法可以做到这一点。

% 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]

You can use 您可以使用

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

But unless you need r and c for other purposes, you can use 但是除非您需要rc用于其他目的,否则可以使用

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

Here is a way to do it using linear indexing: 这是使用线性索引的一种方法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM