【发布时间】:2012-10-12 02:28:51
【问题描述】:
在 matlab 中,我有一个 4x5 单元格数组,其中每个单元格由一个 121x1 向量组成。
创建 3 维 4x5x121 矩阵避免 2 倍循环的最简单方法是什么。
【问题讨论】:
标签: matlab matrix concatenation cell-array
在 matlab 中,我有一个 4x5 单元格数组,其中每个单元格由一个 121x1 向量组成。
创建 3 维 4x5x121 矩阵避免 2 倍循环的最简单方法是什么。
【问题讨论】:
标签: matlab matrix concatenation cell-array
一种方式(不一定是最快的)
%# convert all arrays in the cell array inCell to 1x1x121
permCell = cellfun(@(x)permute(x,[3,2,1]),inCell,'uniformOutput',false);
%# catenate
array = cell2mat(permCell);
【讨论】:
cellfun 需要 uniformoutput = false
permCell = cellfun(@(x)permute(x,[3,2,1]),inCell,'uniformOutput',false);
假设
A = cellfun(@(~)rand(121,1), cell(4,5), 'uniformoutput', false)
那么通常我会说
cat(3, A{:})
但这会给出一个 121×1×20 的数组。对于您的情况,需要一个额外的步骤:
A = cellfun(@(x)permute(x,3,2,1), A, 'uniformoutput', false)
A = reshape([A{:}], size(A,1), size(A,2), size(A{1},3))
或者,或者,
A = cellfun(@(x)permute(x,3,2,1), A, 'uniformoutput', false)
A = cell2mat(A);
虽然
>> start = tic;
>> for ii = 1:1e3
>> B1 = reshape([A{:}], size(A,1), size(A,2), size(A{1},3)); end
>> time1 = toc(start);
>>
>> start = tic;
>> for ii = 1:1e3
>> B2 = cell2mat(A); end
>> time2 = toc(start);
>>
>> time2/time1
ans =
4.964318459657702e+00
所以命令cell2mat 几乎比扩展的reshape 慢5 倍。使用最适合您的情况的选项。
【讨论】:
乔纳斯和罗迪的答案当然很好。一个小的性能改进是 reshape 单元格中的向量,而不是 permute 它们:
permCell = cellfun(@(x)reshape(x,[1 1 numel(x)]), inCell, 'uni',false);
A = reshape([permCell{:}], [size(inCell) numel(inCell{1,1})]);
到目前为止,如果您可以放宽对输出尺寸的要求,那么最快的方法就是连接单元向量并重新整形
A = reshape([inCell{:}], [numel(inCell{1,1}) size(inCell)]);
产生一个[121 x 4 x 5] 矩阵。
【讨论】:
cat(3, A{:})快(好吧你说对输出尺寸的要求可以放宽:)
size(cat(3, c{:})) ans = 121 1 20
这样怎么样,避开cellfun:
output=permute(cell2mat(permute(input,[3 1 2])),[2 3 1]);
虽然没有将速度与其他建议进行比较。
【讨论】: