基于第一列中的数字拆分矩阵

时间:2012-09-18 09:52:01

标签: matlab matrix

我有一个矩阵,其格式如下:

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 = 
[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]

我通过进行以下循环尝试了这个,但是这给了我所需的矩阵行:

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

矩阵C的结果例如是:

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

我该如何解决这个问题?

其他信息:
实际数据在第一列中的日期为yyyymmdd。数据集跨越了几年,我希望将这个数据集拆分为每年的矩阵,然后是每个月。

2 个答案:

答案 0 :(得分:8)

您可以使用arrayfun来解决此任务:

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)

结果A是一个单元格数组,其内容可以按如下方式访问:

>> 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

要根据第一列中的yyyymmdd格式拆分数据,您可以使用以下内容:

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)

答案 1 :(得分:2)

如果您不知道您将拥有多少输出,最方便的是将数据放入cell array而不是单独的数组中。执行此操作的命令是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,我建议将其分为三列yyyy,mm,dd,如下所示,以便于以后分组:

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