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

时间:2017-07-04 01:13:32

标签: matlab variable-assignment cell-array

我有一个单元格数组,其中每个单元格包含相同大小的矩阵。如何有效地设置数组中每个矩阵的最后一个条目?我试图使用WITH line SKIP 2 LIMIT 1,但它看起来不像分配。

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

cellfun

3 个答案:

答案 0 :(得分:1)

我认为最好的方法是更改​​您的原始输入。你能没有牢房生活吗?通常仅在您拥有异构数据时才使用它们。

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

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

答案 1 :(得分:0)

选项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

如果每个单元格包含相同大小的矩阵并且您的应用程序是时间关键的,那么事实证明将单元格数组转换为数字数组更快,执行操作并将其转换回单元格数组。

% 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

外卖消息

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

答案 2 :(得分: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