在Matlab中设置单元数组中每个矩阵的最后一个值

4
我有一个单元数组,每个单元格都包含一个相同大小的矩阵。如何高效地设置数组中每个矩阵的最后一个条目?我试图利用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

请在一个最小化的工作示例中展示你的代码。 - Brick
3
如果您使用单个循环变量:for n = 1:numel(C); C{n}(end) = 0; end;,则循环可能会稍微更有效。这已经相当简短且易读,我怀疑您使用cellfun不会获得太多效率,而且可能会失去一些清晰度。 - mikkola
3个回答

1
我认为最好的方法是更改您的原始输入。如果没有单元格,你能否继续生活?这些通常只在您拥有异构数据时使用。
尝试将每个单元格制作为数组的一个页面(其中页面是第三维),从而使其成为普通的3D数组。
然后,您应该能够直接索引到每个页面的最后一个条目。

0

选项1

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

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

并执行以下cellfun

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

这将给你一个B单元数组,其中所有末尾的值都被更改为0。

然而,我认为这并不比for循环快多少。实际上,它可能会更慢。我在我的机器上进行了100万个单元元素(100、100、100)的测试,结果如下:

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

选项二

如果每个单元格都包含相同大小的矩阵,并且您的应用程序时间关键,则将单元格数组转换为数值数组,执行操作,然后将其转换回单元格数组会更快。

% 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 秒 用于转换回单元数组,因此您的操作仅需要 0.5 秒快了 5 倍!

为了完整起见,我还对 @LuisMendo 的出色答案 进行了时间测试,结果如下:

with numeric conversion (@LuisMendo): 1.66 sec

要点

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


0

以下是一种无需循环的方法。这样可以:

  • 使单元格包含矩阵(不一定像您的示例中那样只包含向量);以及
  • 使每个单元格的期望值不同(不一定与您的示例中相同)。

代码:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接