我有两个矩阵。一个是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列和来自矩阵B的第10,1列。第二行使用来自矩阵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算法的瓶颈)
答案 0 :(得分:2)
可能使用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
答案 1 :(得分:1)
我认为这可以做你想要的,只用你的简单例子进行测试。
% 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]