2017-01-23 47 views
1

我必須從參數分析中後處理數據,該參數分析具有輸出1D陣列的結果。 我想重塑這個一維數組到一個多維矩陣,它具有我調查參數的維度(按照正確的順序),,這些維度可能在數量上有所不同將可能非常大的一維陣列重塑爲具有可變尺寸的多維矩陣

我可以想出一個基於for循環的函數,但問題是,對於非常大的陣列,我耗盡了RAM。我完全知道這不是實現這個目標的最明智的方法。 我想知道是否有一個更聰明的方式來操縱這樣一個大型數組,並執行與我的功能相同的工作。

function [Tensor, n_dimensions]=reshape_array(Data,ndim) 

n_dimensions=length(ndim); 
n_elements=prod(ndim); 

reshape_string=[]; 
for i=n_dimensions:-1:1 
    if i==1 
    reshape_string=strcat(reshape_string, ' ndim(', num2str(i) , ')])'); 
    elseif i== n_dimensions 
    reshape_string=strcat(reshape_string, ' [ndim(', num2str(i) , ')'); 
    else 
    reshape_string=strcat(reshape_string, ' ndim(', num2str(i) , ') '); 
    end 

end 

invert_string=[]; 
for i=1:n_dimensions 
    if i==1 
    invert_string=strcat(invert_string, 'ndim(', num2str(i) , '),'); 
    elseif i== n_dimensions 
    invert_string=strcat(invert_string, ' ndim(', num2str(i) , ')'); 
    else 
    invert_string=strcat(invert_string, ' ndim(', num2str(i) , '),'); 
    end 

end 

reshape_statement=strcat('reshape(Data,',reshape_string); 
invert_statement=strcat('zeros(',invert_string,');'); 

Tens1=eval(reshape_statement); 
Tens2=eval(invert_statement); 

nLoops=length(ndim); 
str = ''; 
str_dim_tens=''; 
str_dim_indeces=''; 
for i=1:nLoops 
    str = strcat(sprintf('%s \n for i%d=1:',str,i), sprintf('%d',ndim(i))); 
    if i<nLoops 
    str_dim_tens=strcat(str_dim_tens,'i',num2str(i),','); 
    else 
    str_dim_tens=strcat(str_dim_tens,'i',num2str(i)); 
    end 
end 

for i=nLoops:-1:1 
    if i~=1 
    str_dim_indeces=strcat(str_dim_indeces,'i',num2str(i),','); 
    else 
    str_dim_indeces=strcat(str_dim_indeces,'i',num2str(i)); 
    end 
end 

str = strcat(sprintf('%s \n Tens2(%s)=Tens1(%s);',str,str_dim_tens,str_dim_indeces)); 

for i=1:nLoops 
    str = sprintf('%s \n end',str); 
end 

eval(str) 

Tensor=Tens2; 

end 

作爲一個例子,

ndim=[2 3]; 
Data=1:2*3 
[Tensor, n_dimensions]=reshape_array(Data,ndim); 

n_dimensions = 

    2 

Tensor = 

    1  2  3 
    4  5  6 

我將與多個尺寸的工作(例如,最小4)和數據陣列與數以百萬計的元素。一個例子可能是M(10,10,10,300000) 這就是爲什麼我正在尋找計算量最少的方法來完成這項工作。

謝謝你的幫助!

回答

5

從你的代碼中,你想要使用與column-major默認相反的尺寸順序來填充重構數組中的元素;也就是說,你從最後dimenson,那麼第二最後等

這可以通過變形與以相反的順序的尺寸的陣列(使用reshape)和反轉維度的順序背面來完成(使用開始permute)。

n_dimensions = numel(ndim); 
Tensor = reshape(Data, ndim(end:-1:1)); % reshape with dimensions in reverse order 
Tensor = permute(Tensor, n_dimensions:-1:1); % reverse back order of dimensions 
+1

細胞真的有必要嗎?不重塑接受一個數組作爲形狀輸入? –

+0

好點!我想是的,是的。我稍後會編輯它,現在我必須運行。或自己編輯它,你覺得:-) –

+1

更聰明,更快,更短。謝謝! –