How to find first '1' in every row

64 views (last 30 days)
Kasmayanti Sakaria
Kasmayanti Sakaria on 7 Nov 2017
Edited: Jan on 23 May 2019
Hi,
I have a matrix,
A = [ 0 0 0 0 0 0 1 1 1 1 0 0; 0 0 0 0 0 1 1 1 1 0 0 0; 0 0 0 0 0 0 1 1 1 1 0 0]
My question is, how to find the first '1' in each row. I want the output will show like this:
B = [7; 6; 7]
Meaning that, for the first row, the number 1 found on column number 7, second row found in column number 6 and so on.
Thank you in advance for any answered

Accepted Answer

Matt J
Matt J on 7 Nov 2017
[~,B]=max(A,[],2);
  4 Comments
Kasmayanti Sakaria
Kasmayanti Sakaria on 8 Nov 2017
It works. Thank you so much
ME
ME on 20 May 2019
perfect solution! Thanks!

Sign in to comment.

More Answers (3)

Jos (10584)
Jos (10584) on 20 May 2019
Not better than using max (for this type of input), but just to show you an alternative:
A = [ 0 0 0 0 0 0 1 1 1 1 0 0; 0 0 0 0 0 1 1 1 1 0 0 0; 0 0 0 0 0 0 1 1 1 1 0 0]
[c, ~] = find(cumsum(A, 2).' == 1)
  2 Comments
ME
ME on 21 May 2019
another good solution, but for larger matrices slower
tic; [~, B] = max(A,[],2); toc;
tic; [c, ~] = find(cumsum(A, 2).' == 1); toc;
size(A)
Elapsed time is 0.014103 seconds.
Elapsed time is 0.153354 seconds.
ans =
1000 12501
Jos (10584)
Jos (10584) on 21 May 2019
of course it is slower, as it requires three internal loops (cumsum, ==, & find) rather than one :-D

Sign in to comment.


Walter Roberson
Walter Roberson on 23 May 2019
A = [ 0 0 0 0 0 0 1 1 1 1 0 0; 0 0 0 0 0 1 1 1 1 0 0 0; 0 0 0 0 0 0 1 1 1 1 0 0];
c = sum(cumprod(~A,2),2)+1;
I do sometimes use this techique to do a vectorized "find" if the first or last element along a dimension. However it does force you to think carefully about what value is "reasonable" for the case where there is no match. In this form of the code, a row with no 1 would give you a result which is 1 greater than the number of columns.

Jan
Jan on 23 May 2019
Edited: Jan on 23 May 2019
Speed test:
A = randi([0,1], 1000, 12501);
tic; % MAX
[~, B] = max(A,[],2);
toc;
>> 0.007 sec
tic; % CUMSUM
[c, ~] = find(cumsum(A, 2).' == 1);
toc;
>> 0.160 sec
tic; % FOR over rows
n = size(A,1);
d = zeros(1, n);
for k = 1:n
d(k) = find(A(k, :), 1);
end
toc
>> 0.193 sec
tic; % FOR over columns
At = A.';
n = size(At, 2);
e = zeros(1, n);
for k = 1:n
e(k) = find(At(:, k), 1);
end
toc
>> 0.119 sec
tic; % FOR, Accumulate
n = size(A, 2);
d = zeros(size(A,1), 1);
for k = 1:n
m = A(:, k);
d(m & ~d) = k;
if all(d)
break;
end
end
toc
>> 0.009 sec % Worst case: 0.220 sec!!!

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!