想象一下,我有两个阵列:
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
但是它比这更容易理想。
答案 0 :(得分:20)
你可以使用arrayfun轻松地将for循环压缩成一个简单的单行程序:
arrayfun(@(x) find(a == x,1,'first'), b )
另请参阅Scenia's answer了解更新的matlab版本(> R2012b)。
答案 1 :(得分: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
答案 2 :(得分:5)
这是对@Pursuit建议的ismember
方法的修复。这样它可以处理其中一个数字的多次出现,并以正确的顺序返回结果:
[tf,loc] = ismember(a,b);
tf = find(tf);
[~,idx] = unique(loc(tf), 'first');
c = tf(idx);
结果:
>> c
c =
3 6 5
答案 3 :(得分: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
,以证明只找到每个值的第一个匹配项。
答案 4 :(得分:4)
你可以试试这个:
[c,ind_a] = intersect(a,b)
答案 5 :(得分:1)
您是否尝试过ismember
?
c_logical_mask = ismember(a, b);
或
c_indexes = find(ismember(a, b));
答案 6 :(得分:1)
a = [1, 2, 5, 7, 6, 9, 8, 3, 4, 7, 0];
b = [5, 9, 6];
c = dsearchn(a',b');
Matlab要求a和b需要是列向量,因此需要转置。
答案 7 :(得分:1)
与@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