将潜在的非常大的一维数组重塑为尺寸可变的多维矩阵 [英] Reshape potentially very large 1D-array into multidimensional matrix with variable dimensions
问题描述
我必须对参数分析的数据进行后处理,该参数分析的结果是一维数组. 我想将此一维数组重塑为一个多维矩阵,该多维矩阵具有我研究的参数的尺寸(按正确的顺序排列),这些尺寸的数量可能会有所变化.
I have to postprocess data from a parametric analysis which has as output a 1D-array with the results. I would like to reshape this 1D array into a multidimensional matrix which has the dimensions of my investigated parameters (to be in the right order), and those dimensions may vary in number.
我可以想到一个基于for循环的函数,但是问题是在非常大的数组中,我的RAM用完了.我完全意识到这不是执行此操作的最明智的方法. 我想知道是否有更聪明的方法来操纵如此大的数组并完成与我的函数相同的工作.
I could came up with a function based on for-loops, but the problem is that with very large arrays I run out of RAM. I am perfectly aware that this is not the smartest way to do this. I was wondering if there is a smarter way to manipulate such a large array and to do the same job as my function does.
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) 这就是为什么我一直在寻找成本最低的方法来完成这项工作.
I would work with more dimensions (e.g. minimum 4) and Data arrays with millions of elements. An example could be M(10,10,10,300000) This is why I was looking for the least computationally expensive method to do the job.
谢谢您的帮助!
推荐答案
From your code, you want to fill the elements in the reshaped array using a dimension order which is the opposite of Matlab's column-major default; that is, you start from the last dimenson, then the second last, etc.
这可以通过以相反的顺序将尺寸重塑为数组来完成(使用 permute
).
This can be done by reshaping into an array with the dimensions in reverse order (using reshape
) and the reversing the order of dimensions back (using 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
这篇关于将潜在的非常大的一维数组重塑为尺寸可变的多维矩阵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!