假设我有一系列具有不同长度的列向量,那么就计算时间而言,最好的方法是将它们连接成一个矩阵,其中它的大小由最长列和细长柱细胞全都充满了NaN。
编辑:请注意我正在尝试避免使用单元格数组,因为它们在内存和运行时方面都很昂贵。
例如:
A = [1;2;3;4];
B = [5;6];
C = magicFunction(A,B);
结果:
C =
1 5
2 6
3 NaN
4 NaN
答案 0 :(得分:1)
以下代码避免使用cell arrays
,除了估计每个向量中的元素数量,这样可以使代码更清晰。使用cell arrays
进行这一小部分工作的代价不应该太昂贵。此外,varargin
无论如何都会将输入作为单元格数组。现在,您也可以避免使用单元格数组,但最有可能涉及使用for-loops
,并且可能必须为每个输入使用变量名称,这在创建未知函数时并不太优雅。输入数量。否则,代码会使用numeric arrays
,logical indexing
和我最喜欢的bsxfun
,market of runtimes
中的代码必须很便宜。
功能代码
function out = magicFunction(varargin)
lens = cellfun(@(x) numel(x),varargin);
out = NaN(max(lens),numel(lens));
out(bsxfun(@le,[1:max(lens)]',lens)) = vertcat(varargin{:}); %//'
return;
示例强>
脚本 -
A1 = [9;2;7;8];
A2 = [1;5];
A3 = [2;6;3];
out = magicFunction(A1,A2,A3)
输出 -
out =
9 1 2
2 5 6
7 NaN 3
8 NaN NaN
基准测试
作为基准测试的一部分,我们将我们的解决方案与@gnovice's solution进行比较,该解决方案主要基于使用单元阵列。我们打算在避免单元阵列之后看到,如果有的话,我们会得到什么样的加速。这是使用20
向量的基准代码 -
%// Let's create row vectors A1,A2,A3.. to be used with @gnovice's solution
num_vectors = 20;
max_vector_length = 1500000;
vector_lengths = randi(max_vector_length,num_vectors,1);
vs =arrayfun(@(x) randi(9,1,vector_lengths(x)),1:numel(vector_lengths),'uni',0);
[A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18,A19,A20] = vs{:};
%// Maximally cell-array based approach used in linked @gnovice's solution
disp('--------------------- With @gnovice''s approach')
tic
tcell = {A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18,A19,A20};
maxSize = max(cellfun(@numel,tcell)); %# Get the maximum vector size
fcn = @(x) [x nan(1,maxSize-numel(x))]; %# Create an anonymous function
rmat = cellfun(fcn,tcell,'UniformOutput',false); %# Pad each cell with NaNs
rmat = vertcat(rmat{:});
toc, clear tcell maxSize fcn rmat
%// Transpose each of the input vectors to get column vectors as needed
%// for our problem
vs = cellfun(@(x) x',vs,'uni',0); %//'
[A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18,A19,A20] = vs{:};
%// Our solution
disp('--------------------- With our new approach')
tic
out = magicFunction(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,...
A11,A12,A13,A14,A15,A16,A17,A18,A19,A20);
toc
结果 -
--------------------- With @gnovice's approach
Elapsed time is 1.511669 seconds.
--------------------- With our new approach
Elapsed time is 0.671604 seconds.
结论 -
20
向量且最大长度为1500000
,加速时间在2-3x
之间,并且随着我们增加了向量的数量,可以看出加速增加了。结果证明这里没有显示以节省空间,因为我们已经在这里使用了很多。答案 1 :(得分:0)
如果使用单元矩阵,则不需要用NaN填充它们,只需将每个数组写入一列,未使用的元素保持为空(这将是节省空间的方式)。你可以使用:
cell_result{1} = A;
cell_result{2} = B;
这会产生一个2号单元格数组,其中包含元素中A,B的所有元素。或者,如果您希望将它们保存为列:
cell_result(1,1:numel(A)) = num2cell(A);
cell_result(2,1:numel(B)) = num2cell(B);
如果您需要使用NaN 来填充以备将来编码,那么最容易找到您获得的最大长度。创建一个(max_length X Number of arrays)矩阵。
所以假设你有n = 5个数组:A,B,C,D和E.
h=zeros(1,n);
h(1)=numel(A);
h(2)=numel(B);
h(3)=numel(C);
h(4)=numel(D);
h(5)=numel(E);
max_No_Entries=max(h);
result= zeros(max_No_Entries,n);
result(:,:)=NaN;
result(1:numel(A),1)=A;
result(1:numel(B),2)=B;
result(1:numel(C),3)=C;
result(1:numel(D),4)=D;
result(1:numel(E),5)=E;