在MATLAB中将不同长度的列向量连接到矩阵中的最佳方法
假设我有一系列长度不同的列向量,从计算时间的角度来说,最好的方法是将它们连接到一个矩阵中,其中它的大小由最长的列决定,并且拉长的列单元格都填充有NaN 编辑:请注意,我试图避免使用单元格数组,因为它们在内存和运行时间方面都很昂贵 例如:在MATLAB中将不同长度的列向量连接到矩阵中的最佳方法,matlab,matrix,Matlab,Matrix,假设我有一系列长度不同的列向量,从计算时间的角度来说,最好的方法是将它们连接到一个矩阵中,其中它的大小由最长的列决定,并且拉长的列单元格都填充有NaN 编辑:请注意,我试图避免使用单元格数组,因为它们在内存和运行时间方面都很昂贵 例如: A = [1;2;3;4]; B = [5;6]; C = magicFunction(A,B); 结果: C = 1 5 2 6 3 NaN 4 NaN 如果使用单元矩阵,则不需要用NaN填充它们,只需将每个数组写入一列,未使用的元
A = [1;2;3;4];
B = [5;6];
C = magicFunction(A,B);
结果:
C =
1 5
2 6
3 NaN
4 NaN
如果使用单元矩阵,则不需要用NaN填充它们,只需将每个数组写入一列,未使用的元素保持为空(这是节省空间的方法)。您可以使用:
cell_result{1} = A;
cell_result{2} = B;
这将产生一个大小为2的单元格数组,其中包含his元素中a、B的所有元素。或者,如果希望将它们另存为列:
cell_result(1,1:numel(A)) = num2cell(A);
cell_result(2,1:numel(B)) = num2cell(B);
如果您需要为将来的编码填充NaN的,那么最容易找到您得到的最大长度。自己创建一个矩阵(最大长度X阵列数)
假设有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;
下面的代码避免使用
单元数组
,除了估计每个向量中的元素数量之外,这使代码更干净。使用单元阵列
完成这一点点工作的价格应该不会太贵。另外,varargin
会以单元格数组的形式获取输入。现在,您也可以避免使用单元格数组,但这很可能涉及使用for循环
,并且可能必须为每个输入使用变量名,这在创建具有未知输入数的函数时并不太优雅。否则,代码将使用数字数组
、逻辑索引
和我最喜欢的bsxfun
,这在运行时市场上肯定很便宜
功能代码
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;
示例
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
基准测试 作为基准测试的一部分,我们将我们的解决方案与主要基于单元阵列的解决方案进行比较。我们在这里的意图是,在避免使用电池阵列之后,如果有任何加速,我们会得到什么。以下是带有
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
之间,可以看出加速比随着矢量数量的增加而增加。证明这一点的结果并不是为了节省空间,因为我们已经在这里使用了很多在写下我的解决方案后,我发现这个解决方案非常有用。检查gnovice的解决方案。谢谢,我今天稍后会尝试这些解决方案。因为它们在内存和运行时间方面都很昂贵,所以我尽量避免使用单元格数组。@EitanVesely在问题中添加了此注释,这样人们就不会将其作为链接问题的重复内容。@EitanVesely这太好了!:)