2014-11-04 167 views
1

如果A是一系列點的二維座標,例如:用於陣列「ismember」功能有效的替代 - MATLAB

>> A = [1 2; 3 4; 5 6; 7 8; 9 0]; 
A = 
    1  2 
    3  4 
    5  6 
    7  8 
    9  0 

B包含兩個小區,其中每個小區是「A」的一部分而只是x值(第一列)表示,意思是:

>> B = {[3; 7];[5]} 
B = 
    [2x1 double] 
    [  5 ] 

我要尋找一個解決方案,B細胞搜索到A和給那些點的座標。

這是我的代碼這是一個大的數據集的速度很慢:

C = cell (length(B) ,1) 

for i = 1 : length(B) 
    C{i} = A(ismember(A(:,1),B{i},'rows'),:); 
end 

C是正確的答案,包括2個細胞,其是B每個單元的座標:

C = 
    [2x2 double] 
    [1x2 double] 

>> C{1} 
ans = 
    3  4 
    7  8 

>> C{2} 
ans = 
    5  6 

此外,儘管C是正確的答案,我正在尋找更有效的解決方案。可能cellfun

回答

1

您不需要在那裏使用'rows'ismember。所以,你可以做 -

for k = 1 : numel(B) 
    C{i}=A(ismember(A(:,1),B{k}),:); 
end 

不知道這是否會加快你的解決方案,雖然。


作爲第二個方法,這個方法可能會更快(未測試雖然),你可以使用bsxfun -

for k = 1 : numel(B) 
    C{k} = A(any(bsxfun(@eq,A(:,1),B{k}.'),2),:); 
end 

當然,無論使用該方法之前,有做pre-allocate -

C = cell (numel(B) ,1) 
+0

第二種方法看起來不錯。謝謝budy – Iman 2014-11-04 15:21:03

+0

@Iman Awesomeness!您可以收集的任何運行時比較結果? – Divakar 2014-11-04 15:22:10

+0

我今天在我的代碼中優化了很多東西,然後有點難以單獨說出這個函數對這樣的真實數據(> 200萬個點!)的影響。 但是,我運行上面的'A'和'B',它表明你的第二種方法比我的速度快72.5%。做得好! – Iman 2014-11-04 20:19:11

1

這是cellfun版本,雖然我懷疑它比循環更快(甚至可能稍慢):

>> C = cellfun(@(b) A(ismember(A(:,1),b),:), B, 'Uniform',false) 
C = 
    [2x2 double] 
    [1x2 double] 

>> C{:} 
ans = 
    3  4 
    7  8 
ans = 
    5  6 
+0

你說得對。它使它變慢,但仍然是一個不錯的嘗試。謝謝 – Iman 2014-11-04 15:19:58