2014-11-04 157 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