How to find first '1' in every row

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

[~,B]=max(A,[],2);

4 Comments

Hah! Good thinking!
Matt J
Matt J on 7 Nov 2017
Edited: Matt J on 20 May 2019
It's interestingly still the only MATLAB feature that I know of which resembles a row-wise find(x,1) operation.
It works. Thank you so much
perfect solution! Thanks!

Sign in to comment.

More Answers (3)

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

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
of course it is slower, as it requires three internal loops (cumsum, ==, & find) rather than one :-D

Sign in to comment.

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!!!

Categories

Tags

Asked:

on 7 Nov 2017

Edited:

Jan
on 23 May 2019

Community Treasure Hunt

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

Start Hunting!