26

想象一下,我有两个数组:

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

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

4

8 回答 8

20

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

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

另请参阅Scenia对较新的 matlab 版本 (>R2012b) 的回答。

于 2012-07-20T06:59:11.693 回答
18

这实际上是内置于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
于 2014-01-24T15:43:58.677 回答
5

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

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

结果:

>> c
c =
     3     6     5
于 2012-07-20T13:36:17.157 回答
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

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

于 2012-07-20T03:12:32.820 回答
4

你可以试试这个:

[c,ind_a] = intersect(a,b)
于 2013-09-09T18:52:08.860 回答
1

你试过ismember吗?

c_logical_mask = ismember(a, b);

或者

c_indexes = find(ismember(a, b));
于 2012-07-20T03:38:44.167 回答
1
a = [1, 2, 5, 7, 6, 9, 8, 3, 4, 7, 0];
b = [5, 9, 6];
c = dsearchn(a',b');

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

于 2013-08-01T15:24:04.030 回答
1

类似于@tmpearce 的答案,但可能更快:

[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
于 2014-06-24T10:20:11.627 回答