2011-12-09 33 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

相關問題