4

I have a matrix which has the following form:

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 based on the number given in the first column. So I want to split 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 making the following loop, but this gave me the desired 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 then for example:

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

How should I solve this issue?

Additional information:
The actual data has a date in the first column in the form yyyymmdd. The data set spans several years and I want to split this dataset in matrices for each year and after that for each month.

4

2 に答える 2

8

You can use arrayfun to solve this task:

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)

The result A is a cell array and its contents can be accessed 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 an 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)
于 2012-09-18T10:14:05.633 に答える
2

出力の数がわからない場合は、データを個別の配列ではなくセル配列に配置するのが最も便利です。これを行うためのコマンドはMAT2CELLです。これは、データが並べ替えられていることを前提としていることに注意してください。sortrowsコードを実行する前に使用しない場合。

%# 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);

次に、3年目、4か月目のデータに次のようにアクセスします。yearByMonth{3}{4}

編集 データの最初の列がである場合、後でグループ化するのを容易にするために、以下のようyyyymmddに3つの列に分割することをお勧めします。yyyy,mm,dd

ymd = 20120918;
yymmdd = floor(ymd./[10000 100 1])
yymmdd(2:3) = yymmdd(2:3)-100*yymmdd(1:2)
于 2012-09-18T09:59:33.970 に答える