【发布时间】:2017-10-27 11:26:14
【问题描述】:
我正在尝试检索两个大型矩阵之间的完全匹配(特定于行)的索引。我有一个 n x 61 矩阵 A 包含从 0 到 9 的值和另一个 n x 61 矩阵 B ,而这里的每一行包含从 0 到 9 但主要是 NaN 的值(矩阵 B 的每一行中只有 2 到 8 列包含实际数字)。矩阵 A 预计有 150 万到 300 万行,而矩阵 B 大约有 0.2 到 50 万行。以下是设置示例:
% create matrix a with random data
dataSample = [0 9];
numRows = 1000000;
numCols = 61;
A = randi(dataSample,numRows,numCols);
% create matrix B with random data
numRows = 100000;
numCols = 61;
numColsUse = 2:8;
dataRange = 0:9;
B = NaN(numRows,numCols);
for i = 1:size(B,1)
% randomly selet number of columns to fill
numColsFill = datasample(numColsUse,1);
% randomly select column index from available columns
colIdx = datasample([1:numCols],numColsFill);
% randomly select values from 0 to 9
numFill = datasample([0:9],numColsFill);
% insert numbers at respective column in matrix B
B(i,colIdx) = numFill;
end
我想将矩阵 A 的每一行与整个矩阵 B 进行比较并找到完全匹配,其中矩阵 B 的数量与矩阵 A 在其各自位置(列)的数量相匹配 - 因此矩阵 B 中的 NaN 是被忽略。
我可以使用 cellfun 实现所需的结果,我将矩阵 A 分割成几个子集,然后使用自定义函数将子集的行与矩阵 B 中的每一行进行比较,如下所示:
% put all rows of matrix B in single cell
cellB = {B};
% take subset of matrix A and convert to cell array
subA = A(1000:5000,:);
subA = num2cell(subA,2);
% prepare cellB to meet cellfun conditions
cellB = repmat(cellB, [size(subA,1) 1]);
% apply cellfun to retrieve index of each exact match
idxContainer = cellfun(@findMatch, cellB, subA, 'UniformOutput', false);
函数 findMatch 如下所示:
function [ idx ] = LTableEval( cellB, subA )
idxCheckLT = lt(cellB, repmat(subA, [size(cellB,1) 1]));
idxCheckGT = gt(cellB, repmat(subA, [size(cellB,1) 1]));
idxCheck = idxCheckLT + idxCheckGT;
idxSum = sum(idxCheck,2);
idx = find(idxSum == 0);
end
这种方法有效,但似乎效率很低,尤其是在 RAM 方面,因为 cellfun 要求所有输入具有相同的大小,因此需要乘以相同的数据集。关于如何以更有效的方式解决这个问题的任何想法?非常感谢!
【问题讨论】:
-
矩阵减法?
-
A-B==0?减法似乎是可行的方法 -
我同意,减法对于实际比较来说很有意义,并且比我目前的方法要好得多。但是,这并不能解决我更基本的问题,即我想找到一种有效的方法来用每一行 B 减去 A 的每一行。在这方面有什么想法吗?谢谢!
标签: matlab matrix indexing comparison