2011-12-09 35 views
1

我有一个包含某些数字的矢量doneS = [1 5 9]。此外,我有一个矩阵,看起来像这样:matrix = [1 2 6 0 0 9; 8 6 0 0 0 9; 2 2 0 0 5 3]。 我想删除的矩阵,其中在1:end-1列数字包含任意数量的doneS的所有行,因此我会在这个例子: matrix = [8 6 0 0 0 9]删除所有包含某个数字的行

我已经有以下两个解决办法:

for m = doneS 
    matrix(any(matrix(:, 1:end-1) == m, 2), :) = []; 
end 

我还没有找到一个更快的解决方案,它首先找到所有索引中删除,并不会只删除一次,其工作速度更快,因为我测试过它:

log = any(matrix(:, 1:end-1) == doneS(1), 2); 
for m = doneS(2:end) 
    log = log | any(matrix(:, 1:end-1) == m, 2); 
end 
matrix(log, :) = []; 

但是这仍然需要一些时间,我想知道是否有更快的解决方案?

编辑 感谢oli的另一种方法!这里有一个基准脚本:

rows = 2e5; 
cols = 100; 
doneEls = 30; 

% Testingdata 
doneS = int8(round(100*rand(1, doneEls))); 
matrix1 = int8(round(1000*rand(rows, cols))); 
matrix2 = matrix1; 
matrix3 = matrix1; 

tic 
log = any(matrix1(:, 1:end-1) == doneS(1), 2); 
for m = doneS(2:end) 
    log = log | any(matrix1(:, 1:end-1) == m, 2); 
end 
matrix1(log, :) = []; 
t1 = toc 

tic 
for m = doneS 
    matrix2(any(matrix2(:, 1:end-1) == m, 2), :) = []; 
end 
t2 = toc 

tic 
matrix3(any(ismember(matrix3(:, 1:end-1), doneS), 2), :) = []; 
t3 = toc 

isequal(matrix1, matrix2, matrix3) 

回答

1

可以使用功能ismemberismember

doneS = [1 5 9] 
matrix = [1 2 6 0 0 9; 8 6 0 0 0 9; 2 2 0 0 5 3] 

matrix(any(ismember(matrix(:,1:end-1),doneS),2),:)=[] 
+0

看起来不错,谢谢。你只是错过了我只想检查第1列的结尾1,但很简单:矩阵(任何(成员(矩阵(:,1:结束1),doneS),2),:)= []' 。我会基准它看看它是否更快:) – tim

+0

好的,我编辑它。 – Oli

+0

谢谢,刚刚进行了测试,并且大部分时间都比其他方法快。它实际上很大程度上取决于输入数据,其中有很多数学题。如果有人想测试它,我用一个基准脚本更新了最初的帖子。 – tim

1

使用unique还要快:

t1 = 
     1.9354 
t2 = 
     0.97107 
t3 = 
     0.2919 
t4 = 
     0.024983 

rows = 2e5; 
cols = 100; 
doneEls = 30; 

% Testingdata 
doneS = int8(round(100*rand(1, doneEls))); 
matrix1 = int8(round(1000*rand(rows, cols))); 
matrix2 = matrix1; 
matrix3 = matrix1; 

tic 
log = any(matrix1(:, 1:end-1) == doneS(1), 2); 
for m = doneS(2:end) 
    log = log | any(matrix1(:, 1:end-1) == m, 2); 
end 
matrix1(log, :) = []; 
t1 = toc 

tic 
for m = doneS 
    matrix2(any(matrix2(:, 1:end-1) == m, 2), :) = []; 
end 
t2 = toc 

tic 
matrix3(any(ismember(matrix3(:, 1:end-1), doneS), 2), :) = []; 
t3 = toc 


doneSu = unique(doneS); 
tic 
matrix3(any(ismember(matrix3(:, 1:end-1), doneSu), 2), :) = []; 
t4 = toc 
+0

谢谢。实际上,当你使用'unique()'时,你也可以在使用ismember-alternative之前使用它,而ismember则更快:-)实际上,我忘记说'doneS'总是唯一的:)因此,我会坚持ismember替代! – tim

+0

好点。我更新了答案。 – cyborg

相关问题