Finding the indices of the elements of one array in another

605 ビュー (過去 30 日間)
Alan
Alan 2011 年 12 月 3 日
コメント済み: David 2020 年 1 月 18 日
Given two vectors A and B, find the index, idx into A of the element of B so that
A(idx)=B.
Now I know there must be many ways it can be done, but is there a one-liner?
For example if
A=[3 4 5 6 7];
B=[6 4 7];
then
[tf,loc]=ismember(A,B);
idx=[1:length(A)];
idx=idx(tf);
idx=idx(loc(tf));
disp(A(idx))
will do it but that is four steps. Is there a more elegant way?
  3 件のコメント
Philip
Philip 2014 年 9 月 26 日
MATLAB supports logical indexing. No need to use "find":
A = A( ismember( A, B ) );
Leandro Coelho
Leandro Coelho 2016 年 7 月 1 日
Another option: intersect(A,B)

サインインしてコメントする。

採用された回答

Sven
Sven 2011 年 12 月 3 日
編集済み: MathWorks Support Team 2018 年 11 月 9 日
There are a few options to get the indices you are looking for. The following output indices (idx) preserve the order in A of the shared values:
[sharedvals,idx] = intersect(A,B,stable)
You can also use the following command if the order in A is not necessary:
[tf,idx] = ismember(B,A)
  3 件のコメント
Alan
Alan 2011 年 12 月 3 日
I am wondering though if "intersect" and "sort" would be expensive on large arrays.
tc88
tc88 2016 年 8 月 22 日
meanwhile, the functionality of intersect has changed and a one-line solution is also possible using intersect:
[sharedVals,idxsIntoA] = intersect(B,A,'stable')
Be aware that the order of A and B must be changed, since the order of the first argument is retained.

サインインしてコメントする。

その他の回答 (6 件)

Alan
Alan 2011 年 12 月 3 日
Thanks for the three solutions. Here is a function to test all three. "method_1" wins as the most elegant and fastest, but the other two taught other useful ways of looking at the problem.
function test_solution
% set up the problem
N=1e6;
% A is a random vector of the integers to N
A=randperm(N);
% B is another vector of integers
B=[ 2 1 4 3 ];
% I'd like to find the indicies of the element of B in A
% such that A(idx)=B;
tic
idx=method_1(A,B);
toc
disp(A(idx));
tic
idx=method_2(A,B);
toc
disp(A(idx));
tic
idx=method_3(A,B);
toc
disp(A(idx));
function idx = method_1(A,B)
idx = arrayfun(@(x)find(A==x,1),B);
function idx = method_2(A,B)
[~,idx1] = intersect(A,B);
[~,idx2] = sort(B);
idx=idx1(idx2);
function idx = method_3(A,B)
[A,idx1] = sort(A);
[~,idx2] = histc(B,A);
idx = idx1(idx2);
  3 件のコメント
Iftikhar Ali
Iftikhar Ali 2015 年 10 月 18 日
Method 3 has solved my problem, thanks.
David
David 2020 年 1 月 18 日
Method one also works if there are multiple occurences of B in A. Intersect fails in this case.

サインインしてコメントする。


Alan
Alan 2011 年 12 月 6 日
Thinking again, I realize that ismember is all I need
[~,idx]=ismember(B,A)
will do it.
  2 件のコメント
normanius
normanius 2017 年 10 月 9 日
This is by far the best answer!
John Sogade
John Sogade 2020 年 1 月 2 日
obviously this will fail to get A(idx), if any elements of idx are 0 (i.e. B not in A) and robust usage should be clarified to A(idx(idx ~= 0)).

サインインしてコメントする。


Iftikhar Ali
Iftikhar Ali 2015 年 10 月 18 日
I am facing an issue finding indices of element matching in two arrays.
xpts = [0 0.0004 0.0011 0.0018 0.0025 0.003]; x = 0:0.0001:0.003; index1 = find(ismember(x, xpts));
It returns index1 = [1 5 12 26 31]
but there is one more element '0.0018' in x which also belongs xpts, and not including in the answer.
Similarly when I increase the number of points in x, there are few elements that are missed or not recognized by the find command. What's going wrong here.

Teja Muppirala
Teja Muppirala 2011 年 12 月 3 日
If A is sorted, then I think this is probably the easiest (and also fastest?) way to do it.
[~,idx] = histc(B,A)
If A is not sorted, then:
[As,s_idx] = sort(A);
[~,tmp] = histc(B,As);
idx = s_idx(tmp)

Stephen Politzer-Ahles
Stephen Politzer-Ahles 2014 年 7 月 8 日
編集済み: Stephen Politzer-Ahles 2014 年 7 月 8 日
The following should also work for your situation, and just needs one line:
A=[3 4 5 6 7];
B=[6 4 7];
idx = arrayfun( @(x)( find(A==x) ), B );

Junhong YE
Junhong YE 2014 年 7 月 21 日
I think find(ismember(A,B)) would do it.

カテゴリ

Help Center および File ExchangeOperating on Diagonal Matrices についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by