taking mean of certain range ignorning NaN in matrix
Show older comments
I have a matrix Phi of size 500x359 with NaNs interspersed throughout. I need to take the column wise mean of the first 25 rows of non-NaN values for each column, but unlike nonmean() I dont want to consider rows with NaNs as rows at all. I want them to be skipped over completely. So I want to kinda of do the following nanmean(Phi(1:25)) where 1 is the first nonmean value regardless of its actual location in the matrix whether its the 1, 100, 200 etc and take the mean of the following 25 non-Nan values regardless of the location.
For example:
X=magic(4); X([1 3 7:9 14]) = repmat(NaN,1)
X =
NaN 2 NaN 13
5 11 10 NaN
NaN NaN 6 12
4 NaN 15 1
nanmean(X(1:2,3)) ans =
10
but what I want is (10+6)/2 = 8
and... so my end result would look like this...
phi_mean = [4.5000 6.5000 8 12.5000]
thank you
5 Comments
Adam
on 25 Sep 2014
nanmean(X(2:3,3))
would be what you want if you are selectively choosing just the two rows your expectation suggests you want.
That doesn't answer your bigger question, just the confusion of your example.
Adam
on 25 Sep 2014
Yeah, I also found your example to actually be an example of something completely separate to your question which is why I initially got thrown off by just pointing out the obvious problem above before realising that was irrelevant to the actual question!
Brandon
on 25 Sep 2014
Adam
on 25 Sep 2014
nanmean(X(1:2,3)) returns the mean of the first two values in the 3rd column, ignoring NaNs, but since that is just two values, one of which is a NaN it simply returns the second value of 10.
Accepted Answer
More Answers (2)
Adam
on 25 Sep 2014
hasNans = any( isnan(Phi), 2 );
validIdx = find( ~hasNans, 25 );
will give you the first 25 row indices which you can then use for your mean calculation.
2 Comments
Brandon
on 25 Sep 2014
Adam
on 25 Sep 2014
It would probably help if you can give an example of what you actually want output to look like for a given small input that represents the problem you have, but on a small scale. The example you gave does not seem to do that and your explanation of what you want included the phrase 'I dont want to consider rows with NaNs as rows at all' which I took to mean that you wish to ignore all rows with a NaN anywhere in them. If that is the case then if every row has a NaN somewhere you would get an empty result.
As far as I understand, you wish to calculate the mean of the first 25 non-NaN values in each column. This can be achieved easily using a couple of find calls. Using your example matrix X :
>> N = 2;
>> K = arrayfun(@(k)find(c==k,N),1:size(X,2),'UniformOutput',false);
>> K = horzcat(K{:});
>> [r,c] = find(~isnan(X));
>> mean(X(sub2ind(size(X),r(K),c(K))),1)
ans =
4.5 6.5 8 12.5
Or a much tidier solution is with some indexing:
>> N = 2;
>> Y = ~isnan(X);
>> mean(reshape(X(cumsum(Y,1)<=N & Y),N,[]),1)
ans =
4.5 6.5 8 12.5
Categories
Find more on Logical in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!