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

137 views (last 30 days)
antonet on 2 Jul 2012
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
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.

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
antonet on 2 Jul 2012
thank you!

Walter Roberson on 2 Jul 2012
Stealing ideas and optimizing...
function y = myUnique(x)
y = unique(x);
y(isnan(y(1:end-1))) = [];
end
Kye Taylor on 3 Jul 2012
That is cool.

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.
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.

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 CommentsShowHide 1 older comment
antonet on 2 Jul 2012
thank you Sean!