2015-08-25 69 views
0

查找值的新MATLAB陣列專欄中,我有一個MATLAB雙陣列看起來像這樣:基於來自兩個陣列

YEAR QUARTER ID VAR 
2000 1  1 50 
2000 1  2 20 
2000 1  3 67 
2000 2  1 43 

它去了很多年,許多宿舍,行數在每個季度和每年的變化不可預測。變量構成個人的估計。

另一雙陣列看起來像這樣:

YEAR QUARTER OUTCOME 
2000 1  100 
2000 2  0 

它去了很多年,很多宿舍。每個季度只有一個結果。我想從結果中減去該人的估計值並將結果放入初始數組中。

結果應該是這樣的:

YEAR QUARTER ID VAR RESULT 
2000 1  1 50 50 
2000 1  2 20 80 
2000 1  3 67 33 
2000 2  1 43 43 

什麼是實現這一目標的最佳方式是什麼?

回答

1

這裏有三個選項,取決於所需的速度/可讀性/假設。

%% Load data 
estimate = [... 
    2000 1  1 50; ... 
    2000 1  2 20; ... 
    2000 1  3 67; ... 
    2000 2  1 43; ... 
    2000 4  1 50]; 
outcome = [... 
    2000 1  100; ... 
    2000 2  0; ... 
    2000 4  0; ... 
    2001 1  10]; 
n_estimate = size(estimate,1); 
n_outcome = size(outcome,1); 

%% Loop version (easier to read, more flexible) 

result = zeros(n_estimate,1); 
for i = 1:n_estimate 
    % Find matching year & quarter for this estimate 
    j = all(bsxfun(@eq, outcome(:,1:2), estimate(i,1:2)),2); 
    % Subtract estimate from outcome (seems like you want the absolute value) 
    result(i) = abs(outcome(j,3) - estimate(i,4)); 
end 

% Append the result to the estimate matrix, and display 
estimated_result = [estimate result]; 
display(estimated_result); 

%% Vectorized version (more efficient, forced assumptions) 
% Note: this assumes that you have outcomes for every quarter 
% (i.e. there are none missing), so we can just calculate an offset from 
% the start year/quarter 
% The second-last outcome violates this assumption, 
% causing the last estimate to be incorrect for this version 

% Build an integer index from the combined year/quarter, offset from 
% the first year/quarter that is available in the outcome list 
begin = outcome(1,1)*4 + outcome(1,2); 
j = estimate(:,1)*4 + estimate(:,2) - begin + 1; 

% Subtract estimate from outcome (seems like you want the absolute value) 
result = abs(outcome(j,3) - estimate(:,4)); 

% Append the result to the estimate matrix, and display 
estimated_result = [estimate result]; 
display(estimated_result); 

%% Vectorize version 2 (more efficient, hardest to read) 
% Note: this does not assume that you have data for every quarter 

% Build an inverted index to map year*4+quarter-begin to an outcome index. 
begin = outcome(1,1)*4 + outcome(1,2); 
i = outcome(:,1)*4+outcome(:,2)-begin+1; % outcome indices 
j_inv(i) = 1:n_outcome; 

% Build the forward index from estimate into outcome 
j = j_inv(estimate(:,1)*4 + estimate(:,2) - begin + 1); 

% Subtract estimate from outcome (seems like you want the absolute value) 
result = abs(outcome(j,3) - estimate(:,4)); 

% Append the result to the estimate matrix, and display 
estimated_result = [estimate result]; 
display(estimated_result); 

輸出:

estimated_result =

2000   1   1   50   50 
    2000   1   2   20   80 
    2000   1   3   67   33 
    2000   2   1   43   43 
    2000   4   1   50   50 

estimated_result =

2000   1   1   50   50 
    2000   1   2   20   80 
    2000   1   3   67   33 
    2000   2   1   43   43 
    2000   4   1   50   40 

estimated_result =

2000   1   1   50   50 
    2000   1   2   20   80 
    2000   1   3   67   33 
    2000   2   1   43   43 
    2000   4   1   50   50 
+0

這個效果非常好! 'j = all(bsxfun(@eq,outcome(:,1:2),estimate(i,1:2)),2);'部分將產生一個向量[1 0 0 0 .... ]。如果我想採取並使其[0 1 0 0 0 ...]怎麼辦?之所以這樣說,是因爲在後面的一些數據集中,QTR1 2000的結果將在另一個陣列的QTR2 2000旁邊,所以一切都需要向下移動。 – user1205197

+1

這個j是一個掩碼,你可以用'j = find(j,1,'first')'將它轉換爲索引,然後給它加1。在向量化版本中,j是一個索引向量,所以你可以直接給它們加1。 – kmac

+0

P.S.如果此答案解決了您的問題,則可以通過單擊複選標記來接受解決方案。 ;) – kmac