2015-08-25 35 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