treating NaN as a unique value (instead of as a distinct)

118 views (last 30 days)
In
there is the following example:
Unique Values in Array Containing NaNs
A = [5 5 NaN NaN];
C = unique(A)
C =
5 NaN NaN
unique treats NaN values as distinct.
IS it possible to treat NaN as a unique value so at to have
C=5 NaN
  1 Comment
Malcolm Lidierth
Malcolm Lidierth on 2 Jul 2012
NaNs are treated as "bigger" than +Inf by Arrays.sort() in Java and by MATLAB unique/sort too by the look of it so you can just trim the output array.
If MATLAB NaN does not return a constant NaN bit pattern (it probably does), java.lang.Double.NaN will do. But NaNs are NaNs so each is treated as unique even if the bit pattern is the same.

Sign in to comment.

Accepted Answer

Kye Taylor
Kye Taylor on 2 Jul 2012
Edited: Kye Taylor on 2 Jul 2012
Write this function...
function y = myUnique(x)
y = unique(x);
if any(isnan(y))
y(isnan(y)) = []; % remove all nans
y(end+1) = NaN; % add the unique one.
end
end

More Answers (3)

Walter Roberson
Walter Roberson on 2 Jul 2012
Stealing ideas and optimizing...
function y = myUnique(x)
y = unique(x);
y(isnan(y(1:end-1))) = [];
end
  5 Comments

Sign in to comment.


James Tursa
James Tursa on 2 Jul 2012
Edited: James Tursa on 3 Jul 2012
Assuming the input A is double class and all the NaN values have the same underlying bit pattern (which seems to be true of the MATLAB functions):
C = typecast(unique(typecast(A,'uint64')),'double');
If you are working with single class variables then:
C = typecast(unique(typecast(A,'uint32')),'single');
The above code has two extra data copies involved. If you don't want to absorb the time/resource penalty of these data copies, you can use my TYPECASTX function from the FEX which returns a shared data copy of the input:
C = typecastx(unique(typecastx(A,'uint64')),'double');
If you are working with single class variables then:
C = typecastx(unique(typecastx(A,'uint32')),'single');
TYPECASTX can be found here:
---------------------------------
WARNING -- WARNING:
---------------------------------
The above code should not be used because the UNIQUE function does not work with uint64 and int64 class inputs. I am leaving my post here for reference, but do not use the above code. See the discussion in the comments below.
  4 Comments
James Tursa
James Tursa on 3 Jul 2012
Edited: James Tursa on 3 Jul 2012
FOLLOW-UP #2:
As I suspected, it wasn't hard to come up with uint64 numbers that did not work for R2010b and later. Bottom line is UNIQUE is buggy for uint64 and int64 class inputs in all versions of MATLAB as far as I can tell because of the underlying silent conversion to / from double.

Sign in to comment.


Sean de Wolski
Sean de Wolski on 2 Jul 2012
Replace the NaNs with an obscure number that you check to make sure is not present first. This will give you the full functionality of unique
function [u, ia, ic] = nanunique(varargin)
x = varargin{1};
t = rand;
while any(x(:)==t)
t = rand;
end
x(isnan(x)) = t;
[u, ia, ic] = unique(x,varargin{2:end});
u(u==t)=nan;
end
Then call it with something like:
nanunique([5 5 2 7 nan nan 5])
  2 Comments

Sign in to comment.

Tags

Community Treasure Hunt

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

Start Hunting!