Удалить все строки, содержащие одно из нескольких чисел - PullRequest
1 голос
/ 09 декабря 2011

У меня есть вектор 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, :) = [];

Но это все же занимает некоторое время, и мне интересно, есть ли какое-нибудь более быстрое решение для этого?

РЕДАКТИРОВАТЬ Спасибо Оли за другой подход!Вот эталонный скрипт:

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 ]

1 голос
/ 09 декабря 2011

Использование 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
1 голос
/ 09 декабря 2011

Вы можете использовать функцию 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),:)=[]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...