Andi
Andi

Reputation: 4899

MATLAB: Inserting different number of NaNs in matrix

I am looking for a solution to insert a different number of NaNs into the first rows of a matrix. Let's assume I have a 20x3 double matrix and a 1x3 double row vector called numNaNs. The row vector contains the number of NaNs that I would like to insert into the matrix.

For example, let's assume numNaNs = [3, 5, 7]. What would the code looks like to replace the first 3 rows of column 1 in the matrix with NaNs, as well as the first 5 rows of column 2 in the matrix, and the first 7 rows of column 3 in the matrix?

I tried something like this:

mat(1:numNaNs, :) = nan;

However, this only replaces the first 3 rows in all columns with NaNs.

Upvotes: 2

Views: 167

Answers (4)

Andy Campbell
Andy Campbell

Reputation: 2187

@nilZ0r's solution is brilliant, but let me take that a step forward now that R2016b has implicit expansion and bsxfun is not needed:

A = rand(20,3);
numNaNs = [3, 7, 5];

% Number of rows 
N = size(A,1);

% Replace with NaN
A((1:N)' <= numNaNs) = NaN

A =

       NaN       NaN       NaN
       NaN       NaN       NaN
       NaN       NaN       NaN
    0.1890       NaN       NaN
    0.6868       NaN       NaN
    0.1835       NaN    0.9797
    0.3685       NaN    0.4389
    0.6256    0.5502    0.1111
    0.7802    0.6225    0.2581
    0.0811    0.5870    0.4087
    0.9294    0.2077    0.5949
    0.7757    0.3012    0.2622
    0.4868    0.4709    0.6028
    0.4359    0.2305    0.7112
    0.4468    0.8443    0.2217
    0.3063    0.1948    0.1174
    0.5085    0.2259    0.2967
    0.5108    0.1707    0.3188
    0.8176    0.2277    0.4242
    0.7948    0.4357    0.5079

Upvotes: 2

NLindros
NLindros

Reputation: 1693

A short version would be to use bsxfun with the built in function le (less than or equal)

% Create test data
A = rand(20,3);
numNaNs = [3, 7, 5];

% Number of rows (to keep the last line cleaner)
N = size(A,1);

% Replace with NaN
A(bsxfun(@le, (1:N)', numNaNs)) = NaN;

Upvotes: 3

Some Guy
Some Guy

Reputation: 1797

You can do this using bsxfun and function handles:

mat = rand(20,3); % Sample matrix to transform
numNaNs = randi(20,1,3); % Sample index matrix
numNaNs =

    18    14    14

mat_new = bsxfun(@(x,y)[NaN(y,1); x(y+1:end)],mat,numNaNs)

mat_new =

       NaN       NaN       NaN
       NaN       NaN       NaN
       NaN       NaN       NaN
       NaN       NaN       NaN
       NaN       NaN       NaN
       NaN       NaN       NaN
       NaN       NaN       NaN
       NaN       NaN       NaN
       NaN       NaN       NaN
       NaN       NaN       NaN
       NaN       NaN       NaN
       NaN       NaN       NaN
       NaN       NaN       NaN
       NaN       NaN       NaN
       NaN    0.0518    0.6663
       NaN    0.0801    0.8035
       NaN    0.0925    0.1394
       NaN    0.4901    0.0614
    0.9647    0.9760    0.1103
    0.7940    0.9753    0.9475

Upvotes: 0

Paul Calcraft
Paul Calcraft

Reputation: 933

The most straightforward solution would be to loop over the columns of the matrix, and fill in the NaNs according to the appropriate value in the numNaNs vector.

M = rand(20, 3);
numNaNs = [3 5 7];
% for each column of numNaNs
for i=1:size(numNaNs,2)
    % set the first numNaNs(i) elements of the ith column to NaN
    M(1:numNaNs(i),i) = NaN;
end

Upvotes: 2

Related Questions