用最近的日记录提取矩阵行:MATLAB

时间:2017-09-11 15:42:53

标签: matlab matrix matrix-multiplication

我有两个矩阵A和B.两个都有不同的大小,第一,第二,第三,和第四个值显示两个矩阵中的年,月,日和值。我需要提取具有相同年份和月份的行,然而,从矩阵A开始+/- 6天,并且相关行形成矩阵B.如果两个或更多天在矩阵A中接近A& B,我应该从两个矩阵中选择对应于最高值的行。

A = 1954    1   16  2,3042
1954    12  5   2,116
1954    12  21  1,9841
1954    12  22  2,7411
1955    1   13  1,8766
1955    10  16  1,4003
1955    12  29  1,4979
1956    1   19  2,1439
1956    1   21  1,7666
1956    11  26  1,7367
1956    11  27  1,8914
1957    1   27  1,151
1957    2   2   1,1484
1957    12  29  1,1906
1957    12  30  1,3157
1958    1   10  1,6186
1958    1   20  1,1637
1958    2   6   1,1639
1958    10  16  1,1444
1959    1   3   1,7784
1959    1   24  1,1871
1959    2   20  1,2264
1959    10  25  1,2194
1960    6   29  1,2327
1960    12  4   1,7213
1960    12  5   1,373
1961    3   21  1,7149
1961    3   27  1,4404
1961    11  3   1,3934
1961    12  5   1,777
1962    2   12  2,1813
1962    2   16  3,5776
1962    2   17  1,9236
1963    9   27  1,6164
1963    10  13  1,786
1963    10  14  1,9203
1963    11  22  1,7575
1964    2   2   1,4402
1964    11  15  1,437
1964    11  17  1,7588
1964    12  4   1,6358
1965    2   13  1,874
1965    11  2   2,6468
1965    11  26  1,7163
1965    12  11  1,8283
1966    12  1   2,1165
1966    12  19  1,6672
1966    12  24  1,8173
1966    12  25  1,4923
1967    2   23  2,3002
1967    3   1   1,9614
1967    3   18  1,673
1967    11  12  1,724
1968    1   4   1,6355
1968    1   15  1,6567
1968    3   6   1,1587
1968    3   18  1,212
1969    9   29  1,5613
1969    10  1   1,5016
1969    11  20  1,9304
1969    11  29  1,9279
1970    10  3   1,9859
1970    10  28  1,4065
1970    11  4   1,4227
1970    11  9   1,7901

B = 1954    12  28  774
1954    12  29  734
1955    3   26  712
1955    3   27  648
1956    7   18  1030
1956    7   23  1090
1957    2   17  549
1957    2   28  549
1958    2   27  759
1958    2   28  798
1959    1   10  421
1959    1   24  419
1960    12  5   762
1960    12  8   829
1961    2   12  788
1961    2   13  776
1962    2   15  628
1962    4   9   628
1963    3   12  552
1963    3   13  552
1964    2   12  260
1964    2   13  253
1965    12  22  862
1965    12  23  891
1966    1   5   828
1966    12  27  802
1967    1   1   777
1967    1   2   787
1968    1   17  981
1968    1   18  932
1969    3   15  511
1969    3   16  546
1970    2   25  1030
1970    2   26  1030

预期输出是一个新的矩阵C:

C = 1954    12  22  2,7411  1954    12  28  774
1959    1   3   1,7784  1959    1   10  421
1959    1   24  1,1871  1959    1   24  419
1960    12  4   1,7213  1960    12  8   829
1962    2   12  2,1813  1962    2   15  628
1966    12  24  1,8173  1966    12  27  802
1968    1   15  1,6567  1968    1   17  981

如何编写此代码的任何帮助?

1 个答案:

答案 0 :(得分:0)

我认为以下应该做你想做的事 -

要处理年和月边界的重叠,将日期映射到自纪元以来的天数是有用的。第一个函数在任一数据集中查找最早的数据,然后将其格式化为'daysact'函数解释。

function epoch_date_str = get_epoch_datestr(A,B)
    Astr = int2str(A(:,1:3));
    Bstr = int2str(B(:,1:3));
    [epoch_Ay, epoch_Am, epoch_Ad]  = earliest_date(A);
    [epoch_By, epoch_Bm, epoch_Bd]  = earliest_date(B);
    [epoch_y, epoch_m, epoch_d] = earliest_date([epoch_Ay, epoch_Am, epoch_Ad; epoch_By, epoch_Bm, epoch_Bd]);
    epoch_str = int2str([epoch_y, epoch_m, epoch_d]);
    epoch_date_str = regexprep(epoch_str,'\s+','/')
end

然后,此函数计算数据集中从纪元到每个日期的天数,它基本上只是将数据转换为daysact函数接受的格式。

function ndays = days_since_epoch(A, epoch_date_str)
    ndays = zeros(size(A,1),1);
    Astr = int2str(A(:,1:3));
    for i=1:size(Astr,1)
        ndays(i) = daysact(epoch_date_str, regexprep(Astr(i,:),'\s+','/'));
    end
end

现在我们可以继续进行实际的计算 - 我对你提出的'A'矩阵中的第五列感到有点困惑,我认为这是分数,但如果没有,它由{{1}配置变量。同样,6天窗口由A_MATRIX_SCORE_COL配置。

WINDOW_SIZE

我得到的输出与你的不同:

ep_str = get_epoch_datestr(A,B);
ndaysA = days_since_epoch(A, ep_str);
ndaysB = days_since_epoch(B, ep_str);
C = [];

WINDOW_SIZE= 6;
A_MATRIX_SCORE_COL = 5;
for i=1:length(B)
    % Find dates within the date window
    overlaps = find(ndaysA >= (ndaysB(i) - window_size ) & (ndaysA <= (ndaysB(i) + window_size )));
    % If there are multiple matches, choose the highest and append to C 
    if (length(overlaps) > 0)
      [~, max_idx] = max(A(overlaps,A_MATRIX_SCORE_COL));
      match_row = overlaps(max_idx);
      C = [C; A(match_row,:) B(i,:)];
    end
end
C = unique(C,'rows');

但是你的第二行有7天的差异,所以我不希望它被发现。可以通过将window_size增加到7来包含它。

正如您所看到的,如果A中的一行与B中的多个日期相匹配,则可以在C中包含两行。如果您愿意,可以从C中轻松过滤:

C =

   1954     12     22      2   7411   1954     12     28    774
   1959      1     24      1   1871   1959      1     24    419
   1960     12      4      1   7213   1960     12      5    762
   1960     12      4      1   7213   1960     12      8    829
   1962      2     16      3   5776   1962      2     15    628
   1966     12     24      1   8173   1966     12     27    802
   1968      1     15      1   6567   1968      1     17    981
   1968      1     15      1   6567   1968      1     18    932

矩阵“D”就是你的去重复输出。