【问题标题】:Calculating a new MATLAB array column based on looking up values from two arrays基于从两个数组中查找值计算新的 MATLAB 数组列
【发布时间】:2015-08-25 13:01:06
【问题描述】:

我有一个如下所示的 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

实现这一目标的最佳方法是什么?

【问题讨论】:

    标签: arrays matlab


    【解决方案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);
    

    输出:

    估计结果 =

        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
    

    估计结果 =

        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
    

    估计结果 =

        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
    

    【讨论】:

    • 这很好用! 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,所以一切都需要向下移动。
    • 那个j是一个掩码,你可以用j = find(j, 1, 'first')把它转换成一个索引,然后加1。在矢量化版本中,j 是索引向量,因此您可以按原样向它们添加 1。
    • P.S.如果此答案解决了您的问题,您可以通过单击复选标记接受该解决方案。 ;)
    猜你喜欢
    • 1970-01-01
    • 2012-11-14
    • 1970-01-01
    • 1970-01-01
    • 2021-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多