How to concentrate 5000 matrices of different row length (same column length) into one matrix by unfolding each of the matrices to the smallest row length

2 views (last 30 days)
Hi all,
I am giving below the code I did for my two following problems (which is partly not working):
  1. I have some 5000 matrices ( each has different number of rows but same number of columns - 1000), and i would like to concentrate them in one single matrix by first cutting all the matrices to the minimum number of rows and then unfolding each of the 5000 matrices into 5000 vectors (concentrating each of them horizontally). So my final matrix X should have dimension 5000-x axis times (number of minimal rows of each matrix times some specific number of selected columns since I plan to work not with all the columns)-y axis.. and I am having problems finding the minimal number of rows for each matrix.
  2. Instead of cutting to the minimal number of rows, I would like to pad all the matrices by adding 0's where needed to have all same number of rows corresponding to the matrix which has the bigest number of rows.
Thank you in advance!
%% Import data from text file.
%% Initialize variables.
d='mypersonaldirectory/data';
for i=1:6
filename = [d sprintf('/NAMEOFFOLDER%05d/nameofcsvfilepereachfolder.csv', i)];
delimiter = ',';
startRow = 2;
%% Create output variable
frametable1final1 = cell2mat(raw);
% Below I select only the columns I really need. I create a matrix for all the matrices I read, transpose them and look for the minimal number. Exactly here not working.
H(i).matrix = frametable1final1(:,[2 3 13 14 15 16 17 18 19 20 24 36 48 49 50 58 59 60 72 73 74 75 76 88 89 90 91 99 263 316 317 318 320 344 357 870 910 927 928 929 948 949 950 969 970 971 975 976 977 981]);
H(i).matrix = H(i).matrix(:).';
a(i) = length(H(i).matrix);
H(i).matrix = H(i).matrix(1,1:min(a));
end
nTrials = 6;
n = 1;
X = []
for i = 1:nTrials
x = H(i).matrix;
X = vertcat(X, x);
end
and the error that I get when starting to consider more than 6 videos (for 5 and less videos works well) is :
Error using vertcat
Dimensions of arrays being concatenated are not consistent.
Error in emotion (line 100)
X = vertcat(X, x);

Accepted Answer

Guillaume
Guillaume on 20 Mar 2019
Where are the 5000 matrices in your code? As far as I can tell you've only got 6 matrices stored in the matrix field of the structure array H.
Assuming that's the matrices you want to concatenate, the number does not matter anyway. Note that you could have achieved the same result as your concatenation loop without a loop in just one line:
%all this code:
X = []
for i = 1:nTrials %ntrials should not be hardcoded to 6 by the way. It should be numel(H)
x = H(i).matrix;
X = vertcat(X, x);
end
%is the same as
X = vertcat(H.matrix); %no loop needed
Of course, if the matrices don't have the same number of rows, it will error.
----
Concatenating all the matrices by shortening the longer ones and reshaping into a vector:
minheight = min(arrayfun(@(s) size(s.matrix, 1), H); %get height of each matrix and get minimum
trimmed = arrayfun(@(s) reshape(s.matrix(1:minheight, :), 1, []), H, 'UniformOutput', false); %trim and reshape matrices
concatenated = vertcat(trimmed{:}); %vertically concatenate the lot
----
Concatenating all the matrices by padding the shorter ones and reshaping into a vector:
maxheight = max(arrayfun(@(s) size(s.matrix, 1), H); %get height of each matrix and get maximum
padded = arrayfun(@(s) reshape([s.matrix; zeros(maxheight - size(s.matrix, 1), size(s.matrix, 2))], 1, []), H, 'UniformOutput, false'); %pad and reshape
concatenated = vertcat(padded{:});
I would consider padding with NaNs instead of 0s. In which case, replace zeros by nan in the above.
I would also consider keep your matrices 2D and concatenating them in the 3rd dimension. This means removing the reshape and replacing the vertcat by a cat(3, ...)
  3 Comments
Spresi
Spresi on 28 Mar 2019
Edited: Spresi on 28 Mar 2019
Hi,
Both of them work pretty well. But, I guess I didn't not explain very well the problem that I have. So, I have the matrices who have different number of rows. Lets say one of them is 220x50, the other one is 230x50. And your code would cut at 220. But then the problem is that, even within the matrix 220x50 the 50 columns have different lengths, with the longest being 220 in length, some columns have length 130 and the rest nan, and so one. So I want to cut not to the minimal number of the rows of each matrix, but at the minimal length of each column within those matrices having values and not nan.
Secondly I am willing to add 0's ( not nan ).
Thanks in advance!

Sign in to comment.

More Answers (0)

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!