matlab には、各セルが 121x1 ベクトルで構成される 4x5 セル配列があります。
2 重ループを回避して 3 次元 4x5x121 行列を作成する最も簡単な方法は何ですか?
matlab には、各セルが 121x1 ベクトルで構成される 4x5 セル配列があります。
2 重ループを回避して 3 次元 4x5x121 行列を作成する最も簡単な方法は何ですか?
片道 (必ずしも最速であるとは限りません)
%# 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);
仮定する
A = cellfun(@(~)rand(121,1), cell(4,5), 'uniformoutput', false)
それから通常私は言うだろう
cat(3, A{:})
しかし、それは 121 x 1 x 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
は展開よりもほぼ 5 倍遅くなりreshape
ます。あなたのケースに最も適していると思われるものを使用してください。
Jonas と Rody による回答はもちろん問題ありません。小さなパフォーマンスの改良は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]
これにより行列が得られます。
回避して、これはどうですかcellfun
:
output=permute(cell2mat(permute(input,[3 1 2])),[2 3 1]);
ただし、速度を他の提案と比較していません。