How to find first '1' in every row

64 次查看(过去 30 天)
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

采纳的回答

Matt J
Matt J 2017-11-7
[~,B]=max(A,[],2);
  4 个评论
ME
ME 2019-5-20
perfect solution! Thanks!

请先登录,再进行评论。

更多回答(3 个)

Jos (10584)
Jos (10584) 2019-5-20
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 个评论
ME
ME 2019-5-21
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) 2019-5-21
of course it is slower, as it requires three internal loops (cumsum, ==, & find) rather than one :-D

请先登录,再进行评论。


Walter Roberson
Walter Roberson 2019-5-23
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 2019-5-23
编辑:Jan 2019-5-23
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!!!

类别

Help CenterFile Exchange 中查找有关 Logical 的更多信息

标签

Community Treasure Hunt

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

Start Hunting!

Translated by