基于查找来自两个数组的值计算新的MATLAB数组列

时间:2015-08-25 03:52:32

标签: arrays 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 个答案:

答案 0 :(得分: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