Finding length of a struct, excluding NaN values

I have a struct with the following layout:
T X Y
[0,1] [0, 1] [0,5]
[0] [2] [2]
NaN NaN NaN
NaN NaN NaN
NaN NaN NaN
NaN NaN NaN
I want to find the length of the struct excluding the trailing NaN values at the bottom. So in this case the length would be 2 instead of 6.
I have attached a file with some of the values that I am using and the struct shape. Thanks

 Accepted Answer

You can do this very easily with the accepted answer to your very similar question from two months ago:
Just use the logical variable X:
>> F = @(s)all(structfun(@(a)isscalar(a)&&isnan(a),s)); % or ANY
>> X = arrayfun(F,AllData.Passive)
X =
0 0 0 0 1 1 1 1 1 1 1 0 0 0 0
>> nnz(~X)
ans = 8

4 Comments

Hi Stephen, thanks for your response! I did think of this, as I can just create a new struct without the NaN values and then take the length of that, however (I did not explain myself properly in the question) I am trying to optimise a code I made for particle tracking and doing this takes a very long time when the struct is quite large.
The issue stems from me trying to preallocate my struct with a bunch of NaN values because I heard preallocation helps speed up loops as the struct does not need to be rebuilt every time (from what I know).
My code looks through the struct and finds the nearest neighbour for a particle in the next frame. So if I preallocate my struct with a large amount of NaNs then the code will loop through all of them when I make the i = 1:length(struct) loop. Hence I wanted the code to only run through values that were not NaN.
In fact in this case there are only trailing NaN values so the data comes first, then followed by the NaN values from preallocation. I have edited my question to reflect this properly
"I can just create a new struct without the NaN values and then take the length of that..."
Sure you could do that...
But that is not what my answer does, so I don't really see how your comment is relevant to my answer. My answer gives code that counts the "length" of the structure (as you use the term), excluding the NaN values as you requested, without generating any new structures.
"Hence I wanted the code to only run through values that were not NaN..."
Sure, just as I stated in my answer: you can use the logical X variable:
find(~X)
Hi Stephen, yes sorry your answer does indeed give the length of a struct without including any NaN values. I was just mentioning that for me when the struct becomes quite large (lengths of around 1000000) the code:
X = arrayfun(F,AllData.Passive)
becomes very slow. I have tried a workaround
if isnan(AllData.Passive(j).PX)
break
end
which just breaks out of the loop when it comes across a NaN value.
This seems to work much faster.
Your suggestion is however much more universal in that it can be applied to structs where there are NaN values scattered around the struct and do not only form below the useful data.
Thanks
@Manny Kins: a well-designed loop will most likely be faster than arrayfun.

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2019a

Tags

Asked:

on 8 Jul 2019

Edited:

on 8 Jul 2019

Community Treasure Hunt

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

Start Hunting!