# mean value of subarrays

15 views (last 30 days)
Hassan on 22 Apr 2011
I have a 3-dimensinal array ( 1483 rows, 417 columns and 4 bands). I am trying to get a mean value for each sub-array of 92rows*92columns. I have some zero values that I want to exclude when the calcualtion of mean is being done. I used the following code but it's not correct.my data type is uint32. i apperciate your help.

Sean de Wolski on 22 Apr 2011
A couple of calls to convn. The first call will determine the number of zeros; the second will calculate the sum of all values in the sub array; array divide the second by the first.
If you don't want to do it to EVERY POSSIBLE subarray, use blkproc or blockproc with function handle
@(x)sum(x(:))./(sum(logical(x(:)))
Also be aware that since your data type is uint32, if the sum of the 92*92*4 values exceeds 4,294,967,295 it will truncate to 4,294,967,295 and your mean will be wrong.
Sean de Wolski on 22 Apr 2011
doc blkproc. The function I wrote would be the handle you would feed it.
Something like:
mean_wout_zeros = blkproc(Data,[92 92],@(x)sum(x(:))./(sum(logical(x(:))));
But I just remembered that blkproc is only for 2-dimensions so forget the whole thing.

Sean de Wolski on 22 Apr 2011
Here's a 2-dimensional example that demonstrates the logic and kernels.
%sample data
A = uint32(repmat(magic(10),[4,1]));
A(A<10) = 0;
%We will use a window size 6x10
window = ones(6,10);
nnzeros = conv2(double(logical(A)),window,'valid'); %you can change this shape do whatever it is you want at the edges.
winsum = conv2(double(A),window,'valid');
mean_wout_zeros = winsum./nnzeros;
%check that it worked (for first valid value)
isequal(sum(sum(A(1:6,:)))/nnz(A(1:6,:)),mean_wout_zeros(1))
You could convert mean_wout_zeros back to uint32 if you want...
Hassan on 22 Apr 2011
As I said I need an array of ean values (16 rows,5coulmns,4 abnds) mean values while using the qhat you said above, I got vecotr of 5540 elements.
it seems blkproc,as you wrote the code above, does what I need.
thanks for the help Sean.