How to find the index of the first element which is greater than a particular value in a matrix for all the columns.
119 views (last 30 days)
DARSHAN KUMAR BISWAS on 10 Jun 2022
Suppose I have a 300 by 300 matrix, containg the values from 0 to 200. For each column, I want to find the position of the first element which is greater than 50. how do I do it. I have tried to write a code but can't do it any further.
Stephen23 on 10 Jun 2022
Edited: Stephen23 on 10 Jun 2022
N = 5;
M = randi(9,5,7)
Method one: CUMSUM and FIND:
X = M>N;
X = X & cumsum(X,1)<2;
[R,~] = find(X)
Method two: FIND and ACCUMARRAY:
[Rx,Cx] = find(M>N);
R = accumarray(Cx,Rx,,@min)
Method three**: NUM2CELL and CELLFUN (fails if there is no such element in any column):
F = @(v)find(v>N,1,'first');
R = cellfun(F,num2cell(M,1))
More Answers (4)
Image Analyst on 10 Jun 2022
Try this. It's a loop but only 300 iterations for it's fast, completing in 0.001 seconds:
% Prepare sample image because user forgot to upload the data.
grayImage = 200 * rand(300);
subplot(1, 2, 1);
[rows, columns] = size(grayImage);
% Now scan across columns finding the first row where the value exceeds 200.
topRows = nan(1, columns);
for col = 1 : columns
t = find(grayImage(:, col) > 50, 1, "first");
topRows(col) = t;
toc % Takes 0.001 seconds for me
% Plot the location of the top rows.
subplot(1, 2, 2);
plot(topRows, 'r.', 'MarkerSize', 15);
ylabel('First row where value > 200')
Mathan on 10 Jun 2022
Edited: Mathan on 10 Jun 2022
[no_row,no_col] = size(c);
Index_final = ;
for ii = 1:no_col
Index = [Index jj]; % Index contains all the elements greater than 50 in that particular column
Index_final = [Index_final Index(1)]; % Index_final should contain all the required elements in your case.
Jan on 10 Jun 2022
Edited: Jan on 10 Jun 2022
s1 = 300;
s2 = 300;
C = randi([0, 200], s1, s2); % Test data
N = 50; % Search
R = nan(s2, 1); % Pre-allocate the output array
for i2 = 1:s2 % Loop over columns
for i1 = 1:s1 % Loop over rows
if C(i1, i2) >= N % Compare the element
R(i2) = i1; % Store in output
break; % Stop "for i1" loop
This is a loop approach equivalent to C or even Basic. Actually Matlab offers more elegant command, see Stephen23's answer. But these "vectorized" methods are slower in modern Matlab versions, because they have to create temporary arrays. The CPU is much faster than the RAM (especially if the data sizes exceed the 1st and 2nd level caches). So this ugly code is much faster than the other suggestions.
This is the case for larger arrays also: I've tested it with 30'000x30'000 matrices.