简体   繁体   English

在MATLAB中找到矩阵中每列有非零元素的行中的最低位置

[英]Find the lowest location within rows where there are non-zero elements for each column in a matrix in MATLAB

For example, I have a 4x6 matrix A: 例如,我有一个4x6矩阵A:

A =

     0     0     0     0     4     3
     0     2     1     0     0     0
     0     5     0     8     7     0
     8     9    10     3     0     2

I want to find the lowest location within the rows of A where non-zero elements are found for each column. 我想找到A行中的最低位置,其中为每列找到非零元素。 It should go like this: 它应该是这样的:

column 1 => row 4
column 2 => row 2 
column 3 => row 2
column 4 => row 3
column 5 => row 1
column 6 => row 1  

And the result should look like the following vector: 结果应该类似于以下向量:

Result = [4, 2, 2, 3, 1, 1] 

Anyone has any idea how to obtain this? 任何人都知道如何获得这个?

One approach to solve for a generic case - 解决一般案例的一种方法 -

[valid,idx] = max(A~=0,[],1)
out = idx.*valid

Sample run - 样品运行 -

A =
     0     0     0     0    -4     3
     0     2     1     0     0     0
     0     5     0     8     7     0
     0     9    10     3     1     2
out =
     0     2     2     3     1     1
  • As seen from the sample run, for a case when there are all zeros (column-1), we get output of zero to indicate that there are no non-zeros in that column. 从样本运行中可以看出,对于存在全零(列-1)的情况,我们得到zero输出以指示该列中没有非零。

  • It also takes care of negative numbers (column-5). 它还负责负数(第5列)。

This should do it: 这应该这样做:

A = [0, 0, 0, 0, 4, 3;
     0, 2, 1, 0, 0, 0;
     0, 5, 0, 8, 7, 0;
     8, 9, 10, 3, 0, 2];

indices = repmat((1:size(A))', [1, size(A, 2)]);
indices(A == 0) = NaN;
min(indices, [], 1)

Here indices is: 这里的指数是:

indices =

1   1   1   1   1   1
2   2   2   2   2   2
3   3   3   3   3   3
4   4   4   4   4   4

We then set every element of indices to NaN wherever A is zero, which gives us: 然后,我们将indices每个元素设置为NaN无论A为零,这给了我们:

indices = 

NaN   NaN   NaN   NaN     1     1
NaN     2     2   NaN   NaN   NaN
NaN     3   NaN     3     3   NaN
  4     4     4     4   NaN     4

We then simply take the minimum of each column 然后我们简单地采用每列的最小值

I can think of one combination that uses ind2sub and unique with find , I'm sure there's a better way. 我可以想到一个使用ind2subfind unique组合,我相信有更好的方法。

With your given A , assuming it's an array of integers: 使用给定的A ,假设它是一个整数数组:

[r, c] = ind2sub(size(A), find(A ~= 0));
[~, ia, ~] = unique(c);
result = r(ia)';

Returns: 返回:

result =

     4     2     2     3     1     1

I did it this way because find returns the linear indices of the array it's searching. 我这样做是因为find返回它正在搜索的数组的线性索引 MATLAB arrays are stored column-major in memory, so it's as if each column is stacked on top of the other. MATLAB数组存储在内存中的列专用,因此就好像每列都堆叠在另一列之上。 ind2sub converts these linear indices back to their subscripts based on the size of the original array. ind2sub根据原始数组的大小将这些线性索引转换回其下标。 Then I use unique to find the first instance of each column and return those row numbers only. 然后我使用unique来查找每列的第一个实例并仅返回那些行号。

一种可能的解决方案,使用sumcumsum

Result = sum(cumsum(A ~= 0) == 0) + 1;

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

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