Finding the indices of the elements of one array in another

조회 수: 626 (최근 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 CenterFile Exchange에서 Operating on Diagonal Matrices에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by