【问题标题】:Setting the last value of each matrix in a cell array in Matlab在Matlab中设置单元格数组中每个矩阵的最后一个值
【发布时间】:2017-12-07 07:33:49
【问题描述】:

我有一个单元格数组,其中每个单元格都包含一个大小相同的矩阵。如何有效地设置数组中每个矩阵的最后一个条目?我试图使用cellfun,但看起来不可能分配。

最小的工作示例(我能想到的最有效的实现):

C = cell(5, 6, 7);
[C{:}] = deal(ones(10, 1));
for i = 1:5
    for j = 1:6
        for k = 1:7
            C{i,j,k}(end) = 0;
        end
    end
end

【问题讨论】:

  • 在一个最小的工作示例中显示您的代码。
  • 如果您使用单个循环变量:for n = 1:numel(C); C{n}(end) = 0; end;,循环可能会更有效。这已经很短了,可读性很好,我怀疑使用cellfun 会提高效率——虽然你可能会失去一些清晰度。

标签: matlab variable-assignment cell-array


【解决方案1】:

我认为最好的方法是更改​​您的原始输入。没有细胞你能活吗?这些通常仅在您拥有异构数据时使用。

尝试使每个单元格成为一个数组的页面(其中页面是第三维)(所以现在它只是一个普通的 3D 数组)。

然后您应该能够直接索引到每个页面的最后一个条目。

【讨论】:

    【解决方案2】:

    这是一种无需循环的方法。这允许

    • 包含矩阵的单元格(不一定是您示例中的向量);和
    • 每个单元格的期望值不同(不一定与您的示例相同)。

    代码:

    C = repmat({zeros(2,3)}, 4, 5, 6); % example cell array with matrices
    values = 1:numel(C); % example vector with numel(C) values. Or it can be a scalar
    t = cat(3, C{:}); % temporarily concatenate all matrices into 3D array
    t(end,end,:) = values; % set last value of each matrix
    C = reshape(num2cell(t, [1 2]), size(C)); % convert back
    

    结果:

    >> whos C
      Name      Size             Bytes  Class    Attributes
    
      C         4x5x6            19200  cell               
    
    >> C{1,1,1}
    ans =
         0     0     0
         0     0     1
    >> C{2,1,1}
    ans =
         0     0     0
         0     0     2
    >> C{4,5,6}
    ans =
         0     0     0
         0     0   120
    

    【讨论】:

      【解决方案3】:

      选项 1

      创建一个函数(例如在一个单独的文件中)

      function x = assignAtEnd(x, v)
        x(end) = v;
      end
      

      并执行cellfun如下

      B = cellfun(@(x) assignAtEnd(x, 0), C, 'UniformOutput', false);
      

      这将为您提供一个 B 单元格数组,其中最后的所有值都更改为 0。

      但是,我不认为这比 for 循环快很多。事实上,它可能会更慢。我用 1.000.000 个单元元素(100、100、100)进行了测试,我的机器上的结果如下

      for-loop (3D): 3.48 sec
      for-loop (1D as per @mikkola): 2.67 sec
      cellfun: 3.06 sec
      

      选项 2

      如果每个单元格都包含一个大小相同的矩阵,并且您的应用程序对时间要求很高,那么将单元格数组转换为数值数组、执行操作并将其转换回单元格数组会更快。

      p>
      % creating the cell
      cellDim = 100;
      matrixDim = 10;
      C = cell(cellDim, cellDim, cellDim);
      [C{:}] = deal(1:matrixDim);
      
      % converting to a 4D numeric matrix
      A = reshape(cell2mat(C), cellDim, matrixDim, cellDim, cellDim);
      % assigning the 0s
      A(:,end,:,:) = 0;
      % converting back to a cell
      B = squeeze(num2cell(A, 2));
      

      事实上,转换回单元格的最后一行花费了大部分时间。手术总耗时

      with numeric conversion: 1.93 sec
      

      但是,其中的1.40 sec 被用于转换回元胞数组,因此您的操作只需要0.5 sec快了5倍!

      为了完整起见,我还对@LuisMendo's great answer做了时间测试,结果是

      with numeric conversion (@LuisMendo): 1.66 sec
      

      外卖留言

      如果您有相同维度的数据,请避免使用元胞数组!使用更高维度的数值数组。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-09-28
        • 2020-05-05
        • 1970-01-01
        • 2014-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多