【问题标题】:Identify sequences of the same number in a matrix识别矩阵中相同数字的序列
【发布时间】:2012-07-30 07:14:34
【问题描述】:

我有矩阵 A

A= [0 0 2 2 2 2 0 0 1 1 1 0 3 3;
    2 2 2 2 0 0 1 1 1 0 0 3 3 0;

如您所见,其中有连续的数字;例如,请注意第一行和第二行的2 2 2 2

对于这个矩阵中出现的每个数字(或者至少对于我的矩阵中从 1 到最大数字的每个数字),我想要一个输出矩阵来指示这个数字和这个数字仅在原始矩阵中的序列。

例如,对于1:第一行有三个连续的数字,第二行有三个:我想在第一个输出矩阵中表示如下:

Matrix 1 = [ 0 0 0 0 0 0 0 0 1 2 3 0 0 0;
             0 0 0 0 0 0 0 1 2 3 0 0 0 0]

号码2也一样:

Matrix 2 = [ 0 0 1 2 3 4 0 0 0 0 0 0 0 0;
             1 2 3 4 0 0 0 0 0 0 0 0 0 0]

3:

Matrix 3 = [ 0 0 0 0 0 0 0 0 0 0 0 0 1 2;
             0 0 0 0 0 0 0 0 0 0 0 1 2 0]

如您所见,每个输出矩阵显示一个数字连续出现的正向计数。

所以在这种情况下,我有 3 个输出矩阵,因为矩阵 A 的最大值为 3。

【问题讨论】:

  • @Gunther Struyf:Struyf 先生,感谢您的补充以明确我的问题。我真的需要帮助来编写这个问题的代码
  • 这样的事情会发生什么:[1 1 1 0 0 2 2 2 0 0 1 1 0]?
  • 这将是 2 个矩阵:第一个只考虑值“1”,第一个矩阵 = [1 2 3 0 0 0 0 0 0 0 4 5 0] 和第二个矩阵只考虑值“2”。第二个矩阵 = [ 0 0 0 0 0 1 2 3 0 0 0 0 0]。
  • @Febri Dwi Laksono:Dan 的意思是如果数字不连续会发生什么。因为在您的示例矩阵中,只有一个相同数字的连续出现序列。
  • 这个怎么样:[1 2 1 2 1] 如果你想得到 [1 0 2 0 3] 和 [0 1 0 2 0] 结果那么下面的答案是完美的。如果不是,那么这个案例的结果应该是什么?

标签: matlab matrix


【解决方案1】:

你可以试试这个:

A= [0 0 2 2 2 2 0 0 1 1 1 0 3 3;
    2 2 2 2 0 0 1 1 1 0 0 3 3 0];

result = arrayfun(@(b) (A == b).*cumsum((A == b),2),nonzeros(unique(A)), 'UniformOutput', false);

对于本例,变量结果中将有 3 个子矩阵。

result = 

    [2x14 double]
    [2x14 double]
    [2x14 double]

要访问它们,请使用以下语法:

result{1}
result{2}
result{3}

然后你得到:

ans =

     0     0     0     0     0     0     0     0     1     2     3     0     0     0
     0     0     0     0     0     0     1     2     3     0     0     0     0     0


ans =

     0     0     1     2     3     4     0     0     0     0     0     0     0     0
     1     2     3     4     0     0     0     0     0     0     0     0     0     0


ans =

     0     0     0     0     0     0     0     0     0     0     0     0     1     2
     0     0     0     0     0     0     0     0     0     0     0     1     2     0

~编辑~
如果按照 cmets 的要求,A 是一个 3D 矩阵,则此代码的工作原理相同,但结果的结构有点不同:

result = 
    [2x14x2 double]
    [2x14x2 double]
    [2x14x2 double]

要访问这些矩阵,例如使用

result{1}(:,:,1) % for the results of comparing A(:,:,1) with value 1
result{1}(:,:,2) % for the results of comparing A(:,:,2) with value 1

【讨论】:

  • 这与@mathematician1975 所做的非常相似,只是写成一行。没有完全矢量化(ARRAYFUN 毕竟有一个循环),但它尽可能紧凑。我猜你们俩都 +1..
  • 其实有一定的相似性(在逻辑上使用 cumsum),但是请注意这个版本会自动提取 A 中的不同值并为每个值传递结果。感谢arrayfun中关于循环的提示,其实我从来没想过。
  • @H.Muster :Muster 先生,当矩阵 A 是 3D 矩阵时,我该怎么办。我觉得很难修改,请先生帮我修改你的代码。
【解决方案2】:

已编辑,因为问题发生了变化

这远非最佳,但会做你想做的事

 V = 1;
 C = A' == V;
 D = cumsum(C).*C
 E = D'

现在 E 在您的示例中将是 Matrix1。将V改为2和3,分别得到Matrix2Matrix3。如果你有类似的东西

 A = [2 2 2 0 0 0 0 0 2 2 2] 

然后你会得到

 [1 2 3 0 0 0 0 0 4 5 6]

所以它可能不是你想要的。从您的问题中不清楚是否是这种情况,但如果不是,请告诉我,我将删除答案

【讨论】:

    【解决方案3】:

    这是一个基于循环的解决方案,可帮助您入门:

    A = [
      0 0 2 2 2 2 0 0 1 1 1 0 3 3;
      2 2 2 2 0 0 1 1 1 0 0 3 3 0
    ];
    
    mx = max(A(:));
    AA = cell(mx,1);
    for num=1:mx
        AA{num} = zeros(size(A));
        for r=1:size(A,1)
            idx = ( A(r,:) == num );
            AA{num}(r,idx) = sum(idx):-1:1;
        end
    end
    

    结果:

    >> AA{1}
    ans =
         0     0     0     0     0     0     0     0     3     2     1     0     0     0
         0     0     0     0     0     0     3     2     1     0     0     0     0     0
    >> AA{2}
    ans =
         0     0     4     3     2     1     0     0     0     0     0     0     0     0
         4     3     2     1     0     0     0     0     0     0     0     0     0     0
    >> AA{3}
    ans =
         0     0     0     0     0     0     0     0     0     0     0     0     2     1
         0     0     0     0     0     0     0     0     0     0     0     2     1     0
    

    编辑:

    更新代码以处理具有三个维度的矩阵:

    A = zeros(2,7,2);
    A(:,:,1) = [2 2 2 0 0 1 1 ; 0 0 2 2 2 1 1];
    A(:,:,2) = [1 1 2 2 2 0 0 ; 0 1 1 0 2 2 2];
    
    mx = max(A(:));
    AA = cell(mx,1);
    for num=1:mx
        AA{num} = zeros(size(A));
        for p=1:size(A,3)
            for r=1:size(A,1)
                idx = ( A(r,:,p) == num );
                AA{num}(r,idx,p) = 1:sum(idx);
            end
        end
    end
    

    结果:

    %# contains consecutive numbers corresponding to number 1 in all slices
    >> AA{1}
    ans(:,:,1) =
         0     0     0     0     0     1     2
         0     0     0     0     0     1     2
    ans(:,:,2) =
         1     2     0     0     0     0     0
         0     1     2     0     0     0     0
    
    %# contains consecutive numbers corresponding to number 2 in all slices
    >> AA{2}
    ans(:,:,1) =
         1     2     3     0     0     0     0
         0     0     1     2     3     0     0
    ans(:,:,2) =
         0     0     1     2     3     0     0
         0     0     0     0     1     2     3
    

    【讨论】:

    • @FebriDwiLaksono:您似乎已将计数更改为向前计数。轻松修复,使用1:sum(idx) 而不是sum(idx):-1:1
    • 先生,如果矩阵A是具有三个维度的矩阵,我该怎么办?,我觉得修改你的代码很难。你能帮帮我吗?
    • @FebriDwiLaksono:你能给我们举一个 3D 矩阵的输入和预期输出的例子吗?
    • 输入:A = val (:,:,1) = [ 2 2 2 0 0 1 1]
    • 输入:A(2,7,2)--> = val (:,:,1) = [ 2 2 2 0 0 1 1; 0 0 2 2 2 1 1]; val(:,:,2) = [ 1 1 2 2 2 0 0; 0 1 1 0 2 2 2]。因此它将创建 2 个输出,其大小为 (2,7,2)--> result{1} = 答案有 2 个值矩阵--> val (:,:,1) 和 val (:,:,1) .结果 {2} = 答案也有 2 个值矩阵 --> val (:,:,1) 和 val(:,:,2)。你明白了吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-04
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多