Split matrix based on the number in the first column

I have a matrix that looks like this:

M = [1 4 56 1; 1 3 5 1; 1 3 6 4; 2 3 5 0; 2 0 0 0; 3 1 2 3; 3 3 3 3] 

I want to split this matrix into the number indicated in the first column. So I want to break the matrix into this:

 A = [1 4 56 1; 1 3 5 1; 1 3 6 4] B = [2 3 5 0; 2 0 0 0] C = [3 1 2 3; 3 3 3 3] 

I tried this by running the following loop, but this gave me the needed matrices with rows of zeros:

 for i = 1:length(M) if (M(i,1) == 1) A(i,:) = M(i,:); elseif (M(i,1) == 2) B(i,:) = M(i,:); elseif (M(i,1) == 3) C(i,:) = M(i,:); end end 

The result for matrix C is, for example, the following:

 C = [0 0 0 0; 0 0 0 0; 0 0 0 0; 2 3 5 0; 2 0 0 0] 

How do I solve this problem?

Additional Information:
The actual data has a date in the first column in the form yyyymmdd . The data set covers several years, and I want to break this data set in matrices for each year, and then for each month.

+4
source share
2 answers

You can use arrayfun to solve this problem:

 M = [ 1 4 56 1; 1 3 5 1; 1 3 6 4; 2 3 5 0; 2 0 0 0; 3 1 2 3; 3 3 3 3] A = arrayfun(@(x) M(M(:,1) == x, :), unique(M(:,1)), 'uniformoutput', false) 

Result A is an array of cells, and its contents can be obtained as follows:

 >> a{1} ans = 1 4 56 1 1 3 5 1 1 3 6 4 >> a{2} ans = 2 3 5 0 2 0 0 0 >> a{3} ans = 3 1 2 3 3 3 3 3 

To split the data based on the yyyymmdd format in the first column, you can use the following:

 yearly = arrayfun(@(x) M(floor(M(:,1)/10000) == x, :), unique(floor(M(:,1)/10000)), 'uniformoutput', false) monthly = arrayfun(@(x) M(floor(M(:,1)/100) == x, :), unique(floor(M(:,1)/100)), 'uniformoutput', false) 
+8
source

If you do not know how many outputs you will get, it is most convenient to put the data in the cell array , rather than in separate arrays. The command for this is MAT2CELL . Please note that this assumes your data is sorted. If it does not use sortrows before running the code.

 %# count the repetitions counts = hist(M(:,1),unique(M(:,1)); %# split the array yearly = mat2cell(M,counts,size(M,2)) %# if you'd like to split each cell further, but still keep %# the data also grouped by year, you can do the following %# assuming the month information is in column 2 yearByMonth = cellfun(@(x)... mat2cell(x,hist(x(:,2),unique(x(:,2)),size(x,2)),... yearly,'uniformOutput',false); 

Then you will get data for the 3rd, 4th month, as yearByMonth{3}{4}

EDIT If the first column of your data is yyyymmdd , I suggest yyyymmdd it into three columns yyyy,mm,dd , as shown below, to facilitate grouping after:

 ymd = 20120918; yymmdd = floor(ymd./[10000 100 1]) yymmdd(2:3) = yymmdd(2:3)-100*yymmdd(1:2) 
+2
source

Source: https://habr.com/ru/post/1434805/


All Articles