2011-12-09 7 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]いくつかの数字のいずれかを含むすべての行を削除します。

をIすでにこれに以下の二つのソリューションを持っている:

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

これにはまだ時間がかかりますが、これにはもっと速い解決策があるのでしょうか?

EDIT 別のアプローチのおかげで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

あなたが機能ismember使用することができます。ismemberuniqueを使用して

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をチェックしたいと思っていなかった:end-1、しかし単純です: 'matrix(any(ismember(行列、:1、end-1)、doneS)、2)、:)= []' 。私はそれが速いかどうかを見るためにそれをベンチマークするつもりです:) – tim

+0

大丈夫、私はそれを編集しました。 – Oli

+0

ありがとう、ちょうどそれをテストし、それは他のアプローチよりも速くほとんどの時間です。実際には入力データに大きく依存しますが、多くの数学があるかどうかにかかわらずです。誰かがテストしたいなら、ちょっとしたベンチマークスクリプトで初期投稿を更新しました。 – tim

1

をさらに高速である:

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-alternativeに固執するでしょう! – tim

+0

良い点。私は答えを更新しました。 – cyborg

関連する問題