MATLAB Answers

Merging array into matrix of unequal size

33 views (last 30 days)
Steeven
Steeven on 13 Apr 2018
Commented: John D'Errico on 13 Apr 2018
A matrix M is preallocated with NaN's:
M=NaN(4,3)
NaN NaN NaN
NaN NaN NaN
NaN NaN NaN
NaN NaN NaN
Then an array x is put into a column:
x=1:4
M(:,2)=x
NaN 1 NaN
NaN 2 NaN
NaN 3 NaN
NaN 4 NaN
This will only work if x is as long as the height of M. My question is about how to efficiently handle cases where x is either too small or too big.
  • In case of a too small x, I want it to replace as much as it can starting from the first row, giving:
x=1:2
M(:,2)=x
_Do-something-so-a-smaller-x-is-accepted_
NaN 1 NaN
NaN 2 NaN
NaN NaN NaN
NaN NaN NaN
  • Whereas in case of a too big x, I want M to grow in height like this:
x=1:5
M(:,2)=x
_Do-something-so-M-will-grow-to-fit_
NaN 1 NaN
NaN 2 NaN
NaN 3 NaN
NaN 4 NaN
NaN 5 NaN
I would like to ask the community for the simplest and most efficient method to merge the matrix and array in this dynamic way, making the matrix grow if needed or allowing for insertion of a too small x if needed in the ways shown above.
The method I use at the moment is with an if-elseif-statement that does concatenation on the matrix with a lot of extra NaN's if x is larger and extension of x with a lot of NaN's if it is smaller. I find it a bit tedious and messy and hope to hear if there is a cleaner solution out there:
if size(x,1) > size(M,1)
fillingUp = nan(size(x,1)-size(M,1) , size(M,2));
M = cat(1,M,fillingUp);
elseif size(x,1) < size(M,1)
fillingUp = nan(1 , size(M,1)-size(x,1));
x = [x fillingUp];
end
M(:,2)=x;

  1 Comment

David Fletcher
David Fletcher on 13 Apr 2018
Presumably you have a specific need to use a matrix rather than a cell array where differing lengths aren't really an issue? If you absolutely have to use a matrix, then the issue is only really manifest if x is larger than the NaN matrix. If it's smaller you don't need to pad x with NaNs, you can just replace the relevant bits of the NaN matrix with the values in x (rather than padding x out and replacing the entire column).

Sign in to comment.

Answers (2)

Stephen Cobeldick
Stephen Cobeldick on 13 Apr 2018
Edited: Stephen Cobeldick on 13 Apr 2018
"I find it a bit tedious and messy and hope to hear if there is a cleaner solution out there"
I doubt it. Sometimes code is tedious and messy. So put it into a function called resizealloc or whatever, and then you can call it and keep the rest of your code nice and tidy.
It is certainly possible to implicitly expand arrays by allocating to elements outside their current size, but this adds zeros for all unallocated values. For adding NaNs there is not much choice apart from doing something like that in your question.

  1 Comment

John D'Errico
John D'Errico on 13 Apr 2018
+1. There is no magical solution, a code that will adjust the size of your array in a way that only you know what you would want to do. But nothing stops you from writing a function that does it for you. So do the work once. If this is what you want to see, and you will need it often, then the beauty of MATLAB is it is fully extensible.

Sign in to comment.


njj1
njj1 on 13 Apr 2018
Why not create the matrix M such that it's size is [numel(x), num_of_desired_columns]? For example, if num_of_desired_columns = 3:
M = NaN(numel(x),3);
M(:,2) = x;
If you want to use the if-else statement, then modify it:
if size(M,1)~=numel(x)
M = NaN(numel(x),3);
M(:,2) = x;
end

  3 Comments

Steeven
Steeven on 13 Apr 2018
Thank you for the suggestion. I can't do that, though, since I might have other columns already inputted into the array. Redefining the matrix M will overwrite other already added columns.
What I didn't show in this simplified example above is that I run the matrix through a loop where different columns are replaced with arrays that are extracted from a user-input file. I am not certain about the size of the user-input arrays and I need to append them all into one matrix. Thus I must be able to handle different dimensions as the questions regards.
njj1
njj1 on 13 Apr 2018
I guess I am not quite sure about the scope of your problem. In your question you talk about replacing only the second column. Is this true? Do all the data have the same number of columns? If so, then instead of using cat() you could just stack them, e.g., M = [M;new_matrix].
It would be useful to explain to full scope of your problem, or at least as much as you can.
njj1
njj1 on 13 Apr 2018
I'll tell you what I'm imagining here and then a solution to that imagined problem.
You have a matrix M which is initialized as M = NaN(n,k). You then have a vector x that is introduced, size(x) = [rx,1]. You want to merge these two matrices. But, let's say you already have some data in M.
M =
NaN 1 NaN
NaN 2 NaN
NaN 3 NaN
NaN 4 NaN
NaN NaN NaN
NaN NaN NaN
So, you want to put the vector x in the second column and grow M around it. My suggestion is to find the row where numerical data is no longer in M and then stack x surrounded by NaN's under M.
if size(x,1)~=size(M,1)
M(isnan(M(:,2)),:) = []; %this blanks out all rows where NaN only exist (rows 4 and 5 in the above example)
M = [M;[NaN(numel(x),1),x,NaN(numel(x),1)]]; %this stacks M on top of new data, x, that is constrained between two columns of NaN's
end

Sign in to comment.