删除包含某些数字的所有行

时间:2011-12-09 07:56:27

标签: matlab optimization logic

我有一个包含某些数字的向量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)

2 个答案:

答案 0 :(得分:1)

您可以使用ismember

功能
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),:)=[]

答案 1 :(得分:1)

unique之前使用ismember的速度更快:

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