Merging array into matrix of unequal size

조회 수: 50 (최근 30일)
Steeven
Steeven 2018년 4월 13일
댓글: John D'Errico 2018년 4월 13일
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
David Fletcher
David Fletcher 2018년 4월 13일
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).

댓글을 달려면 로그인하십시오.

답변 (2개)

Stephen23
Stephen23 2018년 4월 13일
편집: Stephen23 2018년 4월 13일
"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
John D'Errico
John D'Errico 2018년 4월 13일
+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
njj1 2018년 4월 13일
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
njj1
njj1 2018년 4월 13일
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 2018년 4월 13일
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

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Creating and Concatenating Matrices에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by