필터 지우기
필터 지우기

How to count the number of consecutive negative values in a vector?

조회 수: 9 (최근 30일)
V. Luong
V. Luong 2018년 1월 11일
댓글: Image Analyst 2018년 1월 12일
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
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:
V. Luong
V. Luong 2018년 1월 12일
Yes, the data set is loaded only once into a massive array and the variables v1 v2 are just for clearer explanation. Thank you for your comment!

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

채택된 답변

Jonathan Chin
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
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.
  댓글 수: 1
V. Luong
V. Luong 2018년 1월 12일
Thank you very much! Never have I used any functions in Image Processing Toolbox. I will try and see if your solution is faster than Jonathan's.

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


Birdman
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
V. Luong
V. Luong 2018년 1월 12일
편집: V. Luong 2018년 1월 12일
Many thanks to you! I just saved your function 'rcumsum' for upcoming projects. As we are currently working as a team of dozens of members and our highest priority is stability so we have to use built-in functions only
Image Analyst
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?

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

카테고리

Help CenterFile Exchange에서 Matrices and Arrays에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by