将可能非常大的一维数组重塑为具有可变维度的多维矩阵
Reshape potentially very large 1D-array into multidimensional matrix with variable dimensions
我必须对来自参数分析的数据进行后处理,该参数分析的输出是一个包含结果的一维数组。
我想将这个一维数组重塑为一个多维矩阵,该矩阵具有我研究的参数的维度(以正确的顺序排列),并且这些维度的数量可能会有所不同。
我可以想出一个基于 for 循环的函数,但问题是对于非常大的数组,我 运行 内存不足。我很清楚这不是最聪明的方法。
我想知道是否有更聪明的方法来操作如此大的数组并完成与我的函数相同的工作。
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)
这就是为什么我一直在寻找计算成本最低的方法来完成这项工作。
感谢您的帮助!
根据您的代码,您希望使用与 Matlab column-major 默认值相反的维数顺序来填充重塑数组中的元素;也就是说,您从最后一个维度开始,然后是倒数第二个维度,依此类推
这可以通过以相反的顺序(使用 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
我必须对来自参数分析的数据进行后处理,该参数分析的输出是一个包含结果的一维数组。 我想将这个一维数组重塑为一个多维矩阵,该矩阵具有我研究的参数的维度(以正确的顺序排列),并且这些维度的数量可能会有所不同。
我可以想出一个基于 for 循环的函数,但问题是对于非常大的数组,我 运行 内存不足。我很清楚这不是最聪明的方法。 我想知道是否有更聪明的方法来操作如此大的数组并完成与我的函数相同的工作。
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) 这就是为什么我一直在寻找计算成本最低的方法来完成这项工作。
感谢您的帮助!
根据您的代码,您希望使用与 Matlab column-major 默认值相反的维数顺序来填充重塑数组中的元素;也就是说,您从最后一个维度开始,然后是倒数第二个维度,依此类推
这可以通过以相反的顺序(使用 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