[英]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
的逻辑索引选择A
中r==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 但是除非您需要
r
和c
用于其他目的,否则可以使用
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.