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
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 中查找有关 MATLAB 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by