簡體   English   中英

在Matlab中合並兩個矩陣

[英]Merge two matrices in matlab

我有兩個矩陣。 一個尺寸為1,000,000 x 9,另一個尺寸為500,000 x 9。

這些列具有相同的含義,並且前7列具有鍵的功能。 相應地,最后兩列具有數據字符。 在兩個矩陣中都有許多重疊的鍵值,我想有一個大矩陣來比較這些值。 這個大矩陣的尺寸應為1,000,000 x 11。

例如:

A = [0 0 0 0 0 0 0 10 20; 0 0 0 0 0 0 1 30 40];
B = [0 0 0 0 0 0 0 50 60];

合並的矩陣如下所示:

C = [0 0 0 0 0 0 0 10 20 50 60; 0 0 0 0 0 0 1 30 40 0 0];

如您所見,C的第一行包含矩陣A的第8、9列和矩陣B的列10,11。第二行使用矩陣A的第8、9列,最后一個列使用0,0,因為在矩陣B中沒有對應的條目。

理論上,我已經完成了這項任務,但是它非常非常慢。 我經常使用循環。 在任何其他編程語言中,我都將對兩個表進行排序,並在一個大循環中對兩個表進行迭代,並保留兩個指針。

在Matlab中,有沒有使用矢量化的更有效算法,或者至少是慣用/簡短的足夠有效的算法?

(附加說明:我最大的問題似乎是搜索功能:給定矩陣,我想將一個列向量7x1放入其中,讓我們將其命名為key以找到對應的行。現在,我使用bsxfun進行此操作:

targetRow = data( min(bsxfun(@eq, data(:, 1:7), key), [], 2) == 1, :);

我使用min是因為bsxfun的結果是一個帶有7個匹配標志的向量,我顯然希望所有這些標志都是真實的。 在我看來,這可能是Matlab算法的瓶頸)

也許與ismember和一些索引:

% locates in B the last ocurrence of each key in A. idxA has logicals of
% those keys found, and idxB tells us where in B.
[idxA, idxB] = ismember(A(:,1:7), B(:,1:7),'rows'); 
C = [ A zeros(size(A, 1), 2) ];
C(idxA, 10:11) = B(idxB(idxA), 8:9); % idxB(idxA) are the idxB != 0

我認為這可以滿足您的要求,僅通過簡單的示例進行測試。

% Initial matrices
A = [0 0 0 0 0 0 0 10 20;
     0 0 0 0 0 0 1 30 40];
B = [0 0 0 0 0 0 0 50 60];

% Stack matrices with common key columns, 8&9 or 10&11 for data columns
C = [[A, zeros(size(A,1),2)]; [B(:,1:7), zeros(size(B,1),2), B(:,8:9)]];
% Sort C so that matching key rows will be consecutive
C = sortrows(C,1:7);

% Loop through rows
curRow = 1;
lastRow = size(C,1) - 1;
while curRow < lastRow
    if all(C(curRow,1:7) == C(curRow+1,1:7))
        % If first 7 cols of 2 rows match, take max values (override 0s)
        % It may be safer to initialise the 0 columns to NaNs, as max will
        % choose a numeric value over NaN, and it allows your data to be
        % negative values.
        C(curRow,8:11) = max(C(curRow:curRow+1, 8:11));
        % Remove merged row
        C(curRow+1,:) = [];
        % Decrease size counter for matrix
        lastRow = lastRow - 1;
    else
        % Increase row counter
        curRow = curRow + 1;        
    end
end

回答:

C = [0     0     0     0     0     0     0    10    20    50    60
     0     0     0     0     0     0     1    30    40     0     0]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM