How to calculate standard deviation of nonzero elements along the third dimension of a 3D Array

Hi,
I have a 3D-Array called A1, with dimensions 576x640x100.
I want to calculate the standard deviation of elements along the third axis, without taking into account the elements which are equal to 0.
The result would be a 576x640 matrix.
What I have tried :
Since I haven't found a way to use the default function std() in this case, I have tried using 3 loops and calculating the standard deviation using another formula (see figure below)
% Pre-allocate the final result Ds
Ds=zeros(576,640);
% Loop through all lines and columns
for i = 1:576
for j = 1:640
% m is the sum of elements, 'summcar' is the sum of squares m^2
m=0;
summcar=0;
n=100;
for k = 1:100
% if an element = 0 --> substract 1 from number of total elements,
if A1(i,j,k)==0
n=n-1;
else
m = m+A1(i,j,k);
summcar = summcar+m^2;
end
end
if n==0
% if all elements along the third axis are equal to 0 --> assign value 0
Ds(i,j)=0;
else
% np is the sum of all elements that are different than 0
np=sum(A1(i,j,:)~=0);
Ds(i,j)=sqrt(double((summcar-(m^2/np))/np-1));
end
end
end
Formula used for standard deviation (on the right) :
Sample Standard Deviation
Any help is much appreciated.
Thank you.

 Accepted Answer

@hamza lafkiri, did you try the std() function this way:
a = randi(9, 576,640, 100); % Create sample data.
a(a==0) = nan; % Set to nan wherever there is a 0.
stDev = std(a, 0, 3, 'omitnan'); % Compute st dev along the third dimension, ignoring nans.
imshow(stDev, []); % Display resulting image.

4 Comments

Moving my answer here since it is essentially the same.
See the example in the documentation Standard Deviation of 3-D Array.
You would use this syntax to specify which dimension to calculate the standard deviation.
As for ignoring zeros, look at all the synta options. I see there is a syntax for handling NaNs.
So if I can turn the zeros into NaNs, I can ignore them.
The final code might look something like this.
A = data; % 3D array
B = A; % create a copy of matrix
B(A==0) = nan;
stdA = std(B,[],3,'omitnan')
Thank you!. This seems to be the right answer.
I have also tried this code right after I posted the question.
Ds(i,j)=std(double(A1(i,j,A1(i,j,:)~=0)),0,3);
The two methods seem to be yielding the same result so I guess it's the right one.
Thank you. That is indeed it but I guess we first need to convert the zeros to NaN since they're not treated the same way in Matlab, or so I think (please correct me if I'm wrong).
Cris's answer also makes a copy of the original array, unlike mine, in case you don't want to change your original array. However you don't need two copies of data (A & B) -- just one will do. You can then clear it if you want to save memory.
A = data; % Create a copy of original 3-D array
A(A==0) = nan;
stdA = std(A, [], 3, 'omitnan'); % A 3-D array.
clear('A'); % Get rid of temporary variable.

Sign in to comment.

More Answers (0)

Categories

Find more on Interpolation of 2-D Selections in 3-D Grids in Help Center and File Exchange

Products

Release

R2018a

Community Treasure Hunt

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

Start Hunting!