The fastest way to find strings without NaN in Matlab

I would like to find row indexes without NaN in the fastest way, since I need to do this thousands of times. So far I have tried the following two approaches:

find(~isnan(sum(data, 2)));
find(all(~isnan(data), 2));

Is there a smart way to speed it up or is it possible? The dimension of the data matrix is ​​usually from thousands to hundreds.

+5
source share
4 answers

Edit: matrix multiplication can be faster than the sum, so the operation is almost twice as fast for matrices above 500 x500 elements (on my Matlab 2012a machine). So my solution is:

find(~isnan(data*zeros(size(data,2),1)))

Of the two methods you proposed (indicated by fand g) in the question, the first is faster (using timeit):

data=rand(4000);
nani=randi(numel(data),1,500);
data(nani)=NaN;
f= @() find(~isnan(sum(data, 2)));
g= @() find(all(~isnan(data), 2));
h= @() find(~isnan(data*zeros(size(data,2),1)));

timeit(f) 
ans =
     0.0263

timeit(g)
ans =
     0.1489

timeit(h)
ans =
     0.0146
+4
source

nan , . , , nan. , :

%# Preallocate some parameters
T = 5000; %# Number of rows
N = 500; %# Number of columns
X = randi(5, T, N); %# Sample data matrix
M = 100; %# Number of simulation iterations
X(X == 1) = nan; %# Randomly set some elements of X to nan

%# Your first method
tic
for m = 1:M
    Soln1 = find(~isnan(sum(X, 2)));
end
toc

%# Your second method
tic
for m = 1:M
    Soln2 = find(all(~isnan(X), 2));
end
toc

%# A double loop
tic
for m = 1:M
    Soln3 = ones(T, 1);
    for t = 1:T
        for n = 1:N
            if isnan(X(t, n))
                Soln3(t) = 0;
                break
            end
        end
    end
    Soln3 = find(Soln3);
end
toc

:

Elapsed time is 0.164880 seconds.
Elapsed time is 0.218950 seconds.
Elapsed time is 0.068168 seconds. %# The double loop method

, nan , nan . nan , , : -)

+2

,

time = cputime;  
    A = rand(1000,100);              % Some matrix data
    for i = 1:100  
        A(randi(20,1,100)) = NaN;    % Randomly assigned NaN  
        B = isnan(A);                % B has 0 and 1  
        C = A(B == 0);               % C has all ~NaN elements
        ind(i,:) = find(B == 1);     % ind has all NaN indices
    end
    disp(cputime-time)

100 , 0.1404

0

any() , all() sum(). :

idx = find(~any(isnan(data), 2));

: , sum() :

idx = find(~isnan(sum(data, 2)));
0
source

All Articles