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일

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

Chameleon17
Chameleon17 2015년 6월 1일
편집: Walter Roberson 2015년 6월 1일
Hello!
Thank you for that! but unfortunately it is still giving me the same response as last time, a 1 for R1C1 and everything else just zeros..
Chameleon17
Chameleon17 2015년 6월 1일
Is there a way perhaps to just store every row separately, it would be easier to code that way right?
Adam
Adam 2015년 6월 1일
It works fine for me.
You may want to wrap it in a cast to double depending what you want to do with the output as it returns a logical array, but for many purposes a logical array will serve you better anyway.
small example
>> a = [0 1 0 0
1 1 0 0
0 1 0 1
1 0 0 1];
>> out = cumsum(a==1,2)==1 & a==1
out =
0 1 0 0
1 0 0 0
0 1 0 0
1 0 0 0
>>
Here all right?
Chameleon17
Chameleon17 2015년 6월 1일
Okay, yes your example works fine for me, so it's something on my end. It's good to know that it WILL work eventually though! I don't think I understand it though, which isn't good. ==1 & a ==1? What is this saying?
Thanks!
Adam
Adam 2015년 6월 1일
편집: Adam 2015년 6월 1일
should help understand the use of & as an element-wise logical operator. Note that this is different to && which expects scalar operands to AND together into a result.
gives similar information on the == operator's usage.
It did take me quite a while trying to find these in the help because an operator is too short to use as a search term, but they are all under the Language Fundamentals section of the main help.
Chameleon17
Chameleon17 2015년 6월 2일
Ah this is very helpful! Thanks!
Chameleon17
Chameleon17 2015년 9월 9일
편집: Walter Roberson 2015년 9월 9일
Hello Again,
I'm looking over this and I'm still a bit confused.
out = cumsum(a==1,2)==1 & a==1
I understand that the & will replace a 1 if it's true and 0 if it's false. How do you know that it will run during the cumsum(a==1,2)==1. Why does the & ==1 not return a true value for all the values of 1 in each row? Not that I want it to do that. I'm just trying to understand what it's doing.
Thanks
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일

0 개 추천

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

Hi! Thank you very much for the help! I get the idea of what it's doing and I am trying to not have it work in a loop. It only seems to work for column one, row one, after that everything is a zero.
Original:
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
After:
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Is there a way to make it read through each row individually?
Thank you again!
Chameleon17
Chameleon17 2015년 6월 1일
I have tried to specify the rows it needs to work through for the data, but that didn't help either.
I apologize if my questions are extremely simple, I'm very new to this, but I have a lot to learn in a short space of time with MatLab and I keep getting stuck, so yes, any help is very much appreciated :)
idx = find( SP_Square_3(1:28,:) == 1, 1 )
SP_Square_3( (idx + 1):end ) = 0
Adam
Adam 2015년 6월 1일
편집: Adam 2015년 6월 1일
Yes, it definitely won't work without the loop, but your original question suggested you wanted to use a loop to do this so something like this (untested on command line so could be a syntax error. nRows and x are just for pseudo code for you to replace with real data)
for n = 1:nRows
idx = find( x(n,:) == 1, 1 );
x( n,(idx + 1):end ) = 0;
end
Andrei's solution appears to work fine for me for not using a for loop and does actually look similar to a solution I gave to a similar question a while ago so it is a solution I like.
In general though, if speed is not an issue then the question of whether to use a loop or some other alternative that doesn't use a loop is a matter of preference where readability is often the most important factor.
If, when you come back to your own code a week later, you can no longer understand what it is doing because it uses unintuitive methods then it probably isn't worth it.
Obviously if the for loop is slow then finding an alternative is important.
Chameleon17
Chameleon17 2015년 6월 1일
편집: Walter Roberson 2015년 9월 9일
Hi,
Okay, it's still giving me problems, but if you say it works for you there must be something I'm missing, I shall play around with it more.
In terms of understanding the code a bit better too, I have some more questions if you have a moment.
idx = find( x(n,:) == 1, 1 )
In that line of the code, what is the very last 1 doing? The one after the comma.
out = cumsum(a==1,2)==1 & a==1;
For this line of code, I don't understand where it specifies to work with each row independently?
Thanks
Chameleon17
Chameleon17 2015년 6월 1일
I was in logical instead of double... it works now! :) Thank you!
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.

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

카테고리

도움말 센터File Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

태그

질문:

2015년 6월 1일

편집:

2015년 9월 9일

Community Treasure Hunt

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

Start Hunting!

Translated by