【问题标题】:Replace specific matrix position with array value without using for loop in MATLAB用数组值替换特定矩阵位置而不在MATLAB中使用for循环
【发布时间】:2015-05-10 15:32:13
【问题描述】:

我可以知道如何在不使用 MATLAB 中的 for 循环的情况下替换特定矩阵位置的值吗?我初始化矩阵a,我想在每个no 的指定行和列上替换它的值。这必须在num for 循环内完成几次。 num for 循环在这里很重要,因为我希望更新原始代码中的值。

真实代码比较复杂,我正在简化这个问题的代码。

我的代码如下:

a = zeros(2,10,15);



for num = 1:10

    b = [2 2 1 1 2 2 2 1 2 2 2 2 1 2 2]; 
    c = [8.0268 5.5218 2.9893 5.7105 7.5969 7.5825 7.0740 4.6471 ...
    6.3481 14.7424 13.5594 10.6562 7.3160 -4.4648 30.6280];

    d = [1 1 1 2 1 1 1 1 1 1 3 1 6 1 1];

    for no = 1:15
        a(b(no),d(no),no) = c(1,no,:)
    end

end

13 号的示例输出如下:

a(:,:,13) =

  Columns 1 through 8

         0         0         0         0         0      7.3160       0         0
         0         0         0         0         0         0         0         0

  Columns 9 through 10

         0         0
         0         0

非常感谢您为我提供的任何帮助。

【问题讨论】:

    标签: matlab matrix


    【解决方案1】:

    Matlab 提供了一个函数 'sub2ind' 可以达到你的预期。

    变量与您发布的相同:

    idx = sub2ind(size(a),b,d,[1:15]); % return the index of row a column b and page [1:15]
    a(idx) = c;
    

    【讨论】:

      【解决方案2】:

      除了Nras's solution 中建议的基于sub2ind 的方法外,如果性能非常关键,您可以使用"raw version" of sub2ind 来减少函数调用。比较sub2ind 和它的原始版本的相关基准在another solution 中列出。这是解决您的案例的实现-

      no = 1:15
      a = zeros(2,10,15);
      [m,n,r] = size(a)
      a((no-1)*m*n + (d-1)*m + b) = c
      

      对于预分配,您可以使用Undocumented MATLAB blog post on Preallocation performance 中列出的更快的方法 -

      a(2,10,15) = 0;
      

      【讨论】:

        【解决方案3】:

        函数sub2ind是你的朋友:

        a = zeros(2,10,15);
        
        x = [2 2 1 1 2 2 2 1 2 2 2 2 1 2 2];
        y = [1 1 1 2 1 1 1 1 1 1 3 1 6 1 1];
        z = 1:15;
        
        dat = [8.0268 5.5218 2.9893 5.7105 7.5969 7.5825 7.0740 4.6471 ...
            6.3481 14.7424 13.5594 10.6562 7.3160 -4.4648 30.6280];
        
        inds = sub2ind(size(a), x, y, z);
        
        a(inds) = dat;
        

        【讨论】:

          【解决方案4】:

          可以使用sub2ind 来完成,它将subs 转换为线性索引。 按照您模糊的变量名称,它看起来像这样(省略num 上的无用循环):

          a = zeros(2,10,15);
          b = [2 2 1 1 2 2 2 1 2 2 2 2 1 2 2]; 
          d = [1 1 1 2 1 1 1 1 1 1 3 1 6 1 1];
          c = [8.0268 5.5218 2.9893 5.7105 7.5969 7.5825 7.0740 4.6471 ...
          6.3481 14.7424 13.5594 10.6562 7.3160 -4.4648 30.6280];
          
          % // we vectorize the loop over no:
          no = 1:15;
          a(sub2ind(size(a), b, d, no)) = c;
          

          【讨论】:

          • 非常感谢@Nras。
          • @loss 不客气。正如 Divakar 指出的那样:对于原始速度,您可以剥离 sub2ind 以直接计算 3 维情况的线性索引。虽然没有变得更具可读性;-)。此外,根据num 循环中实际发生的情况,您可能可以从该循环中提取一些代码。
          • 注意到@Nras。我会尝试所有的代码,看看哪个适合循环。
          猜你喜欢
          • 2013-12-21
          • 1970-01-01
          • 2014-11-22
          • 1970-01-01
          • 1970-01-01
          • 2020-02-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多