【问题标题】:Find indices of elements in an array based on a search from another array根据从另一个数组中的搜索查找数组中元素的索引
【发布时间】:2012-07-19 07:09:41
【问题描述】:

假设我有两个数组:

a = [1, 2, 5, 7, 6, 9, 8, 3, 4, 7, 0];

b = [5, 9, 6];

我想在 a 中找到 b 值的索引(仅第一次命中),即:

c = [3, 6, 5];

有没有一种简单的 Matlab 原生方法可以做到这一点,而无需循环和搜索。

我曾尝试将 find() 用于:

find(a == b)

如果你这样做,它会起作用:

for i = 1:length(b)
    index = find(a == b(i));
    c = [c, index(1)]
end

但如果它比这更容易,那将是理想的。

【问题讨论】:

标签: arrays matlab search matrix find


【解决方案1】:

您可以使用 arrayfun 轻松地将您的 for 循环压缩成一个简单的单行:

arrayfun(@(x) find(a == x,1,'first'), b )

另请参阅 Scenia's answer 以获取较新的 matlab 版本 (>R2012b)。

【讨论】:

  • arrayfun 并不比 for 循环快
  • @niceman 我从来没有说过它是......而且我相信在某些情况下,当 JIT 启动时它会同样快或更快(尤其是在多核设置上)。另一方面,有些人只是喜欢arrayfun 的oneliner-capability。对于这个问题,它实际上并不重要,因为你最好使用Scenia's answer
【解决方案2】:

这实际上是内置在ismember 中的。你只需要设置正确的标志,然后它是一个单行,你不需要arrayfun。高于 R2012b 的版本默认使用此行为。

最初,ismember 会返回最后一次出现,如果有多个,R2012a 标志使其返回第一个。

这是我的测试结果:

a = [1, 2, 5, 7, 6, 9, 8, 3, 4, 7, 0, 6];
b = [5, 9, 6];

[~,c] = ismember(b,a,'R2012a');
>> c
c =
     3     6     5

【讨论】:

    【解决方案3】:

    这是对@Pursuit 建议的ismember 方法的修复。这样它会处理多次出现的数字之一,并以正确的顺序返回结果:

    [tf,loc] = ismember(a,b);
    tf = find(tf);
    [~,idx] = unique(loc(tf), 'first');
    c = tf(idx);
    

    结果:

    >> c
    c =
         3     6     5
    

    【讨论】:

      【解决方案4】:
      a = [1, 2, 5, 7, 6, 9, 8, 3, 4, 7, 0, 6];
      b = [5, 9, 6];
      [r c]=find(bsxfun(@eq,a,b')');
      [~,ia,~]=unique(c,'first');
      >> r(ia)
      
      ans =
      
           3
           6
           5
      

      注意:我在a 末尾添加了一个额外的6,以演示仅查找每个值的第一次出现。

      【讨论】:

        【解决方案5】:

        你可以试试这个:

        [c,ind_a] = intersect(a,b)
        

        【讨论】:

          【解决方案6】:

          你试过ismember吗?

          c_logical_mask = ismember(a, b);
          

          c_indexes = find(ismember(a, b));
          

          【讨论】:

          • 一些事情:这不会只找到b 的每个值在a 中的第一次出现,而且它也没有使索引保持正确的顺序。跨度>
          • @tmpearce:我发布了对此的修复
          【解决方案7】:
          a = [1, 2, 5, 7, 6, 9, 8, 3, 4, 7, 0];
          b = [5, 9, 6];
          c = dsearchn(a',b');
          

          Matlab 要求 a 和 b 必须是列向量,因此需要转置。

          【讨论】:

            【解决方案8】:

            类似于@tmpearce's answer,但可能更快:

            [valid, result] = max(bsxfun(@eq, a(:), b(:).')); %'// max finds first occurrence
            result = result(valid); %// this is necessary in case some value of b is not in a
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2020-05-22
              • 1970-01-01
              • 2016-09-24
              • 2020-02-08
              • 1970-01-01
              • 1970-01-01
              • 2013-07-19
              • 1970-01-01
              相关资源
              最近更新 更多