【问题标题】:Shifting rows of matrix in matlab在matlab中移动矩阵的行
【发布时间】:2012-04-15 16:14:57
【问题描述】:

我必须在 matlab 中移动某些行。比如说我有一个大小为 50x50 的矩阵。而且我必须移动某些行,比如说 15,18,45.. 到顶部,其余行在底部。如何在 matlab 中完成此操作?

【问题讨论】:

    标签: matlab matrix


    【解决方案1】:

    你试过 circshift 功能吗?这样的事情可能会有所帮助:

    A = [1:8; 11:18; 21:28; 31:38; 41:48]
    A =
         1     2     3     4     5     6     7     8
        11    12    13    14    15    16    17    18
        21    22    23    24    25    26    27    28
        31    32    33    34    35    36    37    38
        41    42    43    44    45    46    47    48
    B = circshift(A, [3, 0])
    B =
        21    22    23    24    25    26    27    28
        31    32    33    34    35    36    37    38
        41    42    43    44    45    46    47    48
         1     2     3     4     5     6     7     8
        11    12    13    14    15    16    17    18
    

    【讨论】:

      【解决方案2】:

      这是一个可以通过一些简单的索引很容易解决的问题:

      Matrix = [ 1   101   201   301
       2   102   202   302
       3   103   203   303
       4   104   204   304
       5   105   205   305
       6   106   206   306
       7   107   207   307
       8   108   208   308
       9   109   209   309
      10   110   210   310];
      
      rowsOnTop = [1 8 4];
      rowsBelow = true(size(Matrix,1),1);
      rowsBelow(rowsOnTop) = false;
      
      Modified = [Matrix(rowsOnTop,:); Matrix(rowsBelow,:)]
      
      Modified =
      
           1   101   201   301
           8   108   208   308
           4   104   204   304
           2   102   202   302
           3   103   203   303
           5   105   205   305
           6   106   206   306
           7   107   207   307
           9   109   209   309
          10   110   210   310
      

      【讨论】:

        【解决方案3】:

        我了解到您希望将某些矩阵行移到顶部,并将其余行保留在原位。为此,您可以使用:

        示例矩阵:

        Matrix = [ 1:10; 101:110; 201:210; 301:310 ]';
        
        Matrix =
        
         1   101   201   301
         2   102   202   302
         3   103   203   303
         4   104   204   304
         5   105   205   305
         6   106   206   306
         7   107   207   307
         8   108   208   308
         9   109   209   309
        10   110   210   310
        

        代码如下:

        RowsVector = [ 3, 5, 8 ];
        

        编辑:新的更好的解决方案(这里首先介绍,因为它更好)。

        NewMatrix = Matrix(cell2mat(arrayfun(@(x) x:size(Matrix,1):prod(size(Matrix)), [ RowsVector, setdiff(1:size(Matrix, 1), RowsVector) ]', 'UniformOutput', false)));
        
        NewMatrix =
        
         3   103   203   303
         5   105   205   305
         8   108   208   308
         1   101   201   301
         2   102   202   302
         4   104   204   304
         6   106   206   306
         7   107   207   307
         9   109   209   309
        10   110   210   310
        

        编辑:答案的其余部分与 [有限] 较旧的解决方案有关。

        % RowsVector must be sorted, otherwise the reordering will fail.
        

        编辑:修复了无序 RowsVector 输入的错误。

        RowsVector = sort(RowsVector);
        
        for RowIndex = 1:size(RowsVector, 2)
            row = RowsVector(RowIndex);
            Matrix = vertcat(Matrix(row,:), Matrix);
            Matrix(row+1,:) = [];
        end
        

        这是结果:

        Matrix =
        
         8   108   208   308
         5   105   205   305
         3   103   203   303
         1   101   201   301
         2   102   202   302
         4   104   204   304
         6   106   206   306
         7   107   207   307
         9   109   209   309
        10   110   210   310
        

        【讨论】:

        • 这要求对RowsVector 进行排序。 RowsVector=[2 1] 将失败。
        • @乔纳斯。谢谢。我编写了一个新的更好的解决方案,其中不存在该问题。
        • 如果您捕获了sort 的附加输出,您可以在循环之后重新排列顶部的行,以便它们按照指定的顺序显示。
        【解决方案4】:

        我会通过定义一个行置换矩阵来解决这个问题,以产生所需的结果。如果 Matlab 对此有一个内置函数,我会忽略它,所以我写了一个:

        function P = rowpermat(vec)
        P = zeros(length(vec));
        for i = 1:length(vec)
            P(i,vec(i)) = 1;
        end
        

        如果vec1:n 的排列,则此函数将返回一个矩阵,该矩阵将排列nxn 矩阵的行1->vec(1), 2->vec(2), ... 请注意缺少错误检查等,因此请在您的生产代码中使用它风险自负。

        在这种情况下,如果 A 是要置换的矩阵,您可以这样写:

        rowpermat([15, 18, 45, 1:14,16:17,19:44,46:50])*A
        

        【讨论】:

        • 如果你努力写出完整的排列,你为什么不直接打电话给out = A([15, 18, 45, 1:14,16:17,19:44,46:50],:)?请注意,我在解决方案中所尝试的只是促进创建排列。
        猜你喜欢
        • 2013-01-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-31
        • 1970-01-01
        • 2015-07-25
        • 2015-07-10
        相关资源
        最近更新 更多