Merging array into matrix of unequal size
12 views (last 30 days)
Show older comments
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
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).
Answers (2)
Stephen23
on 13 Apr 2018
Edited: Stephen23
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
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.
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
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
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
See Also
Categories
Find more on Creating and Concatenating Matrices in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!