4

我有一个具有以下形式的矩阵:

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。该数据集跨越数年,我想将这个数据集拆分为每年的矩阵,之后每个月。

4

2 回答 2

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)
于 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,我建议将其分成三列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 回答