필터 지우기
필터 지우기

How to index on a loop for first occurrence?

조회 수: 3 (최근 30일)
Chameleon17
Chameleon17 2015년 6월 1일
편집: Walter Roberson 2015년 9월 9일
Hi,
I have a set of data which I would like to loop through for each row.
I would like for every row, the first occurrence of a one to cause all other subsequent values in that row to be replaced by a zero.
Does anybody have any advice on how I could go about doing this?
Thanks

답변 (2개)

Andrei Bobrov
Andrei Bobrov 2015년 6월 1일
편집: Andrei Bobrov 2015년 6월 1일
a = [1 0 1 0 0 0 1
1 0 0 0 0 0 0
0 0 0 0 1 0 0
0 0 0 0 0 0 0
0 0 0 1 1 0 0
0 0 0 0 0 0 0
0 0 0 1 0 0 0
0 1 0 0 0 0 0
0 0 0 0 1 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 1 0 0
0 0 0 1 0 0 1
0 0 0 1 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 1
1 0 0 0 0 0 0
0 0 1 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
1 0 0 0 0 1 0
0 0 0 0 0 0 0
0 0 0 0 0 0 1
0 0 0 0 0 0 0
0 0 1 0 0 1 0
0 0 1 0 0 0 0
0 0 0 0 0 1 0
0 0 0 0 1 0 0]
out = cumsum(a==1,2)==1 & a==1;
  댓글 수: 10
Walter Roberson
Walter Roberson 2015년 9월 9일
편집: Walter Roberson 2015년 9월 9일
The ==1 examines each element independently. It does not process row by row.
The & will result in 1 if both values are true, and 0 otherwise. It is a binary operator. The cumsum(a==1,2)==1 part is going to create a logical matrix the same size as "a" and the a==1 part is going to create a logical matrix the same size as "a", and then the & is going to compare corresponding elements one at a time, returning true only if both are set. Another way of writing the code would be
L1 = cumsum(a==1,2)==1;
L2 = a==1;
out = false(size(L1));
for K = 1 : size(L1,2)
for J = 1 : size(L1,1)
out(J,K) = L1(J,K) & L2(J,K);
end
end
In the case where "a" contains only 0 and 1, then the code could be shorter:
out = cumsum(a,2)==1 & a;
or
out = (cumsum(a,2)==1) .* a;
If "a" can contain values other than 0 and 1, then none of the posted versions in this sub-thread are correct. I would need to think more about a good solution for that case.
Chameleon17
Chameleon17 2015년 9월 9일
Thank you! That helps a lot!

댓글을 달려면 로그인하십시오.


Adam
Adam 2015년 6월 1일
idx = find( x == 1, 1 );
x( (idx + 1):end ) = 0;
will do this for an array x. I will leave it up to you to make the trivial change to do it in a loop.
  댓글 수: 7
Adam
Adam 2015년 6월 1일
편집: Adam 2015년 6월 1일
The final 1 after the comma is the 2nd argument to the find function which tells it to just find the first occurrence rather than all occurrences (or some other number than 1 if explicitly defined).
If you don't add that argument you will get all indices on the row corresponding to ones.
For example:
a = [0 0 1 1 0 0 1]
a =
0 0 1 1 0 0 1
>> find( a == 1 )
ans =
3 4 7
>> find( a == 1, 1 )
ans =
3
When I have something like this I don't fully understand I find it invaluable to just create a quick example on the command line so I can see for myself what is going on. It is one of the big advantages of Matalb over, for example, C++ where you need to do a lot more work to just test to see what simple syntax alternatives give you.
Chameleon17
Chameleon17 2015년 6월 2일
Yes, I think that is really good advice, to trial it on smaller data sets, I've already reduced my data set loads to learn how to do this, but yes, nothing is going to replace understanding all the basics properly.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 File Operations에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!

Translated by