This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Dealing with NaN’s in matlab functions
Is there a one line command that allows you to take the elementwise average of a matrix (ignoring NaN's) in Matlab? For example,
>> A = [1 0 NaN; 0 3 4; 0 NaN 2]
A =
1 0 NaN
0 3 4
0 NaN 2
So the mean(A) should equal (1+3+2+4+0+0+0)/7 = 1.4286
Also, I don't have access to the stats toolbox so I cannot use nanmean()
You can use isnan() to filter out the unwanted elements:
mean(A(~isnan(A)))
nanmean
Performs just like mean, but ignoring nans.
For example:
>> A = [1 0 NaN; 0 3 4; 0 NaN 2]
A =
1 0 NaN
0 3 4
0 NaN 2
>> nanmean(A)
ans =
0.333333333333333 1.5 3
>> nanmean(A,2)
ans =
0.5
2.33333333333333
1
>> nanmean(A(:))
ans =
1.42857142857143
Related
May be I don't get a basic thing, but I recently discovered this behaviour, and by now I don't understand what's happening:
A = [3 NaN .12 NaN NaN 9]
A =
3 NaN 0.12 NaN NaN 9
>> nansA = isnan(A)
nansA =
0 1 0 1 1 0
>> nnansA = ~isnan(A)
nnansA =
1 0 1 0 0 1
>> nnansA1 = ~isnan(A(1:end))
nnansA1 =
1 0 1 0 0 1
>> nnansA2 = ~isnan(A(2:end))
nnansA2 =
0 1 0 0 1
>> AnnansA1 = A(~isnan(A(1:end)))
AnnansA1 =
3 0.12 9
>> **AnnansA2 = A(~isnan(A(2:end)))
AnnansA2 =
NaN NaN
What is happening here?
Does this happen in Matlab too?
I would expect something like ... AnnansA2 = 0.12 9
What is happening here is that you're indexing A with a logical array of a different size and expect the indexing to not start at the beginning.
Let's deconstruct, from the inside:
>> A = [3 NaN .12 NaN NaN 9]
A =
3.0000 NaN 0.1200 NaN NaN 9.0000
>> # B a new array, with 5 elements (A had 6 elements)
>> B = A(2:end)
B =
NaN 0.1200 NaN NaN 9.0000
>> # mask is a logical array with 5 elements, like B, and not 6, like A.
>> # mask knows nothing about A or B. It simply "selects" (indexes) the
>> # 1st, 3rd, and 4th element of any array.
>> mask = isnan (B)
mask =
1 0 1 1 0
>> # Invert the mask, now "selects" the 2nd and 5th element of any array.
>> not_mask = ! mask
not_mask =
0 1 0 0 1
>> # Return the 2nd and 5th element of A.
>> A(not_mask)
ans =
NaN NaN
I think you're surprised by the behaviour because you expect that A(2:end) "remembers" that it comes from A to index the right "region" of A. This does not happen, it's just a logical array that "remembers" nothing from which array it came (and often used to index different arrays).
As a side note, and answering one of your questions, Matlab behaviour is the same as Octave.
Anyway, what you're doing looks a bit odd, maybe do this instead:
A(! isnan (A))(2:end)
You're off by one.
You need to do AnnansA2 = A(~isnan(A(1:end)))
If you want to return only the last two non-nans, index the result like;
ananIdxs = ~isnan(A)
AnnansA2 = A(ananIdxs(2:end))
This question already has answers here:
Is there any general way to remove NaNs from a matrix?
(5 answers)
Closed 6 years ago.
New to MATLAB, any help with this would be appreciated.
I have a dataset that is 1000 elements in 1 column, and most of the elements are numbers but some are NaN's. Is there a way I can, 1. Find them, and 2. Remove them and put them in a variable (or just remove them)?
Would I have to do this the reverse way and find and remove the non-NaN's (the numbers) and store them in a variable?
Use logical indexing to extract the elements that are not NaN and then store them anywhere you like. Here's how it works. If x is your column vector containing NaN, y = ~isnan(x) will give a logical vector y such that |y|=|x| and y(i) is 1 iff x(1) is not NaN. You can use this logical vector to extract non NaN elements:
x = [1 2 3 NaN 5 6 NaN NaN 9];
y = ~isnan(x); % now y is [1 1 1 0 1 1 0 0 1]
x = x(y) % now x is [1 2 3 5 6 9]
Logical indexing is powerful and efficient. You could also say:
x = [1 2 3 NaN 5 6 NaN NaN 9];
x(isnan(x)) = -1 % now x is [1 2 3 -1 5 6 -1 -1 9]
For more information on logical indexing see the official Matlab documentation here.
A option equivalent to #sadeghmir's answer:
x = [1 2 3 NaN 5 6 NaN NaN 9];
x(x==NaN)=[];
>x
1 2 3 5 6 9
I have a 3D matrix with NaN padded to obtain equal number of rows in each 2D matrix i.e each (:,:,ind). Now i need to find the number of actual non-NaN rows in each (:,:,ind).
A simple example of what I need:
% Input:
A(:,:,1) = [ 1 1;
2 2;
NaN NaN];
A(:,:,2) = [ 2 2;
NaN NaN;
NaN NaN];
% Function call:
B = callingfunction(A);
% Output:
B = [2 1] % Number of Non-NaN rows in each 2D Matrix
Approach #1
B = squeeze(sum(all(~isnan(A),2),1))
Here's the build-up process to get a hang of it -
Start>>> Given A:
>> A
A(:,:,1) =
1 1
2 2
NaN NaN
A(:,:,2) =
2 2
NaN NaN
NaN NaN
1) Detect all non-NaN positions:
>> ~isnan(A)
ans(:,:,1) =
1 1
1 1
0 0
ans(:,:,2) =
1 1
0 0
0 0
2) Find rows with all non-Nan elements:
>> all(~isnan(A),2)
ans(:,:,1) =
1
1
0
ans(:,:,2) =
1
0
0
3) Sum up the number of all such rows:
>> sum(all(~isnan(A),2),1)
ans(:,:,1) =
2
ans(:,:,2) =
1
4) Get the result as a 1D array:
>> squeeze(sum(all(~isnan(A),2),1))
ans =
2
1
Approach #2
B = squeeze(sum(~any(isnan(A),2),1))
Use the same break-up-my-code-into-pieces process as listed earlier here and in all your future MATLAB codes and all past MATLAB codes that didn't make sense to do so now!
I have a 3x3 matrix, populated with NaN and values of a variable:
NaN 7 NaN
5 NaN 0
NaN NaN 4
matrix = [NaN 7 NaN; 5 NaN 0; NaN NaN 4]
I would like to get the row and column numbers of non-NaN cells and put them in a matrix together with the value of the variable. That is, I would like to obtain the following matrix:
row col value
1 2 7
2 1 5
2 3 0
3 3 4
want = [1 2 7; 2 1 5; 2 3 0; 3 3 4]
Any help would be highly appreciated.
This can be done without loops:
[jj, ii, kk] = find((~isnan(matrix).*(reshape(1:numel(matrix), size(matrix)))).');
result = [ii jj matrix(kk)];
The trick is to multiply ~isnan(matrix) by a matrix of indices so that the third output of find gives the linear index of non-NaN entries. The transpose is needed to have the same order as in the question.
The following should work!
[p,q]=find(~isnan(matrix)) % Loops through matrix to find indices
want = zeros(numel(p),3) % three columns you need with same number of rows as p
for i=1:numel(p)
want[i,:] = [p(i) q(i) matrix(p(i), matrix(i))]
end
Should give you the correct result which is:
2 1 5
1 2 7
2 3 0
3 3 4
If you don't mind the ordering of the rows, you can use a simplified version of Luis Mendo's answer:
[row, col] = find(~isnan(matrix));
result = [row(:), col(:), matrix(~isnan(matrix))];
Which will result in:
2 1 5
1 2 7
2 3 0
3 3 4
This is just a very simple example to show my problem.
a=ones(5)
How can i insert NaN after every two rows like:
I know the way to do this simple example is:
b(:,1:5)=NaN
[a(1:2,:);b;a(3:4,:);b;a(end,:)]
But the problem is if the martrix is 60000-by-200 (may be more larger), so how can i insert 'NaN' after every two rows.
Thanks so much.
a = ones(5); %// example data
n = 2; %// number of rows
N = floor(size(a,1)*(1+1/n)); %// final number of rows
ind = mod(1:N, n+1) ~= 0; %// logical index for non-NaN rows
b = NaN(N,size(a,2)); %// initiallize result to NaN
b(ind,:) = a; %// fill in non-NaN rows
I can't think of an easy, one-line type solution. It can be done in a pretty tight loop though.
a = ones(5);
a_with_nans = nan(floor(size(a,1)*(3/2)), size(a,2)); %Start with all nans in a larger matrix
for ix = 1:2:size(a,1)
a_with_nans(ix*3/2-(1/2),:) = a(ix,:);
if ix+1<=size(a,1)
a_with_nans(ix*3/2-(1/2)+1,:) = a(ix+1,:);
end
end
Then:
a_with_nans =
1 1 1 1 1
1 1 1 1 1
NaN NaN NaN NaN NaN
1 1 1 1 1
1 1 1 1 1
NaN NaN NaN NaN NaN
1 1 1 1 1
You can do it like this:
>> a= [ 1 2 3 4 5 6 7 8 9]
a =
1 2 3 4 5 6 7 8 9
>> b = nan(floor(length(a)/2),1)'
b =
NaN NaN NaN NaN
>> a_new = zeros(1, length(a)+length(b))
a_new =
0 0 0 0 0 0 0 0 0 0 0 0 0
>> b_i = 3:2:length(a)
b_i =
3 5 7 9
>> a_new(b_i+(0:length(b_i)-1)) = b
a_new =
0 0 NaN 0 0 NaN 0 0 NaN 0 0 NaN 0
>> a_new(~isnan(a_new))=a
a_new =
1 2 NaN 3 4 NaN 5 6 NaN 7 8 NaN 9