【问题标题】:Efficient alternative for "ismember" function for arrays - MATLAB数组的“ismember”函数的有效替代方法 - MATLAB
【发布时间】:2014-11-04 13:52:22
【问题描述】:

如果A是一系列二维坐标点,例如:

>> 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

【问题讨论】:

    标签: arrays performance matlab comparison cell-array


    【解决方案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)
    

    【讨论】:

    • 第二种方法看起来很棒。谢谢朋友
    • @Iman 太棒了!您可以收集任何运行时比较结果吗?
    • 我今天在我的代码中优化了很多东西,那么单独对这样一个真实数据(>200万点!)这个函数的效果有点难以说清楚。但是,我在上面的 AB 上运行,它表明您的第二种方法比我的快 72.5%。干得好!
    【解决方案2】:

    这里是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
    

    【讨论】:

    • 你是对的。它使它变慢但仍然是一个不错的尝试。谢谢
    猜你喜欢
    • 2013-03-29
    • 1970-01-01
    • 2014-11-13
    • 1970-01-01
    • 2014-05-26
    • 2014-03-08
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    相关资源
    最近更新 更多