2014-08-28 3 views
1

길이가 다른 일련의 열 벡터가 있다고 가정하면 계산 시간 측면에서 모든 것을 하나의 행렬로 결합하는 가장 좋은 방법은 무엇입니까? 여기서 그것의 크기는 가장 긴 열에 의해 결정되고 긴 열의 셀은 모두 NaN으로 채워집니다.다른 길이의 열 벡터를 MATLAB의 행렬에 결합하는 가장 좋은 방법

편집 : 메모리와 실행 시간면에서 비싸기 때문에 셀 배열을 피하려고합니다. 예를 들어

:

A = [1;2;3;4]; 
B = [5;6]; 

C = magicFunction(A,B); 

결과 :

C = 
    1 5 
    2 6 
    3 NaN 
    4 NaN 
+2

내 솔루션을 작성한 후이 솔루션을 [이전 질문] (http://stackoverflow.com/questions/3054437/how-can-i-accumulate-cells-of-different-lengths-into- 매트릭스 - 인 - 매트랩). gnovice에서 솔루션을 확인하십시오. –

답변

1

다음 코드는 각 벡터의 요소 수의 추정 및 제외 cell arrays의 사용을 피할 A, B, C, D와 E :

그래서 당신이 N = 5 배열이 있다고 할 수 있습니다 이렇게하면 코드가 조금 더 깨끗하게 유지됩니다. 그 작은 작업을 위해 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에 대한 우리의 솔루션을 비교하고 있습니다.셀 어레이를 피한 후 우리가 얻는 속도가 빨라지는 것을 알기위한 우리의 의도입니다.

%// 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 벡터와 벤치마킹 코드의

  1. 20 벡터와 1500000의 최대 길이가의 속도 향상은 2-3x과 사이 우리가 벡터의 수를 늘리면 속도가 빨라 졌다는 것을 알 수있었습니다. 여기에 공간을 절약하기 위해 여기에 표시되지 않은 결과는 이미 많이 사용되었습니다.
+0

작품 대단원입니다! 감사! –

+0

@EitanVesely 매우 좋습니다! :) – Divakar

0

당신이 셀 매트릭스를 사용하는 경우 하나의 열과에 각 배열을 작성, NaN을 가득 수를 필요가 없습니다 사용되지 않는 요소는 비어 있어야합니다 (공간 효율적인 방법).

cell_result{1} = A; 
cell_result{2} = B; 

이렇게하면 요소의 A, B의 모든 요소가 포함 된 크기 2 셀 배열이 생성됩니다. 당신이 원하는 경우 또는 그들을 열로 저장하기 :

cell_result(1,1:numel(A)) = num2cell(A); 
cell_result(2,1:numel(B)) = num2cell(B); 

필요할 경우

는 NaN이의 미래 코딩을위한 가득 할, 당신이있어 최대 길이를 찾을 수있는 가장 쉬운 방법 일 것입니다. 자신에게 max_length X 배열 수의 행렬을 만듭니다.

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; 
+0

고마워, 나는 나중에 오늘 그 해결책을 시도 할 것이다. 메모리와 실행 시간면에서 비싸기 때문에 셀 배열을 피하려고합니다. –

+0

@EitanVesely이 의견을 질문에 추가하여 사람들이이 질문을 링크 된 질문과 중복되지 않도록했습니다. – Divakar

관련 문제