How to count the number of consecutive negative values in a vector?
조회 수: 7 (최근 30일)
이전 댓글 표시
Hello! What is the most time-saving method (using the vectorization style or others but not for loops) to count the maximum number of consecutive negative values in a vector?
The problem is that there are thousands of vectors of the same length and if one contains more than 3 consecutive negative values then it will be removed from the data set. For example, vector v1 will be deleted due to [-1 -1 -3] chain, but v2 will remain:
v1 = [11 2 3 -1 -2 1 -1 -1 -3 1 3 1]
v2 = [3 -1 4 1 33 44 -11 -3 4 11 3 -1]
Can it be get done by using array modifying functions only (like 'repmat', 'diff', 'cumsum' etc. not consuming ones like 'find')?
Many Thanks!
댓글 수: 2
Stephen23
2018년 1월 12일
편집: Stephen23
2018년 1월 12일
"The problem is that there are thousands of vectors..."
That is indeed a major problem of your code design.
Once you put all of your data into lots of separate variables like that then you force yourself to write slow, buggy, complex, obfuscated code when you try to access them. Trying to magically access thousands or variable names is what beginners do because they don't realize that they are making their code and data much slower and buggier.
The simpler, neater, and much more efficient way of accessing data is to use indexing.
The two main ways that beginners end up with thousands of numbered variables in their workspace (magically defining them, or using load) can both be trivially altered to use just one array with indexing, so your best option is to change your code design. Read this to know more:
채택된 답변
Jonathan Chin
2018년 1월 11일
편집: Jonathan Chin
2018년 1월 11일
This might work using cumsum to find all the negatives in a group and hist to count the consecutive negatives
v1 = [11 2 3 -1 -2 1 -1 -1 -3 -1 1 3 1];
v2 = [3 -1 4 1 33 44 -11 -3 4 11 3 -1];
x = [0 cumsum(v1>=0)]; %makes all the values positive increment the sum, so all negative numbers will keep the next number the same
numNeg=max(hist(x)-1); % find number of consecutive negative by looking counting all the similar numbers and subtracting 1 for the initial increment
추가 답변 (2개)
Image Analyst
2018년 1월 11일
I don't see how any of the other answers are getting rid of the vector. You'd need to use the clear function for that. You can use regionprops(), in the Image Processing Toolbox to get the lengths of all the negative runs of values, then clear to get rid of the vector. So try this with your vectors.
% Find lengths of negative values.
props = regionprops(vec < 0, 'Area');
% If 3 negatives in a row or longer, clear vector - get rid of it completely.
if max([props.Area]) >= 3
clear vec;
end
I call it vec, but you'd call the code using v1, v2, v3, v4, ...... v9000. You could put it into a function like
function deleteIt= ClearIf3Negatives(vec)
deleteIt = false;
% Find lengths of negative values.
props = regionprops(vec < 0, 'Area');
% If 3 negatives in a row or longer, clear vector - get rid of it completely.
if max([props.Area]) >= 3
deleteIt = true;
end
Then call it like
if ClearIf3Negatives(v1), clear(v1), end;
if ClearIf3Negatives(v2), clear(v2), end;
...
if ClearIf3Negatives(v9000), clear(v9000), end;
But PLEASE tell me you don't actually have thousands of separately named vectors like you said. That would be such bad programming practice.
Birdman
2018년 1월 11일
편집: Birdman
2018년 1월 12일
Download the file from the link and use rcumsum function.
idx=find(rcumsum(v1<0)==3);
v1([idx-2:1:idx])=[];
(EDITED)
I understood that those consecutive negative values should be deleted from the array, therefore my answer looks like this. To delete v1, just type
idx=find(rcumsum(v1<0)==3);
if ~isempty(idx)
clear v1;
else
end
댓글 수: 2
Image Analyst
2018년 1월 12일
regionprops(), max(), and clear() (used in my solution) are built in functions. rcumsum() is not a built-in function - it's a user-submitted function, though it's built upon built in functions.
I also question why you need to clear the vector. I virtually never clear variables except if I'm using to many large image arrays that I need to because otherwise the user would run out of RAM memory. Normally, I just let the garbage collector free up the space automatically when the function returns. Why do you think you need to call clear?
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!