Reputation: 527
A =[1;2;3;4;5]
B= [10 1 ;11 2;19 5]
I want to get
D = [1 10 ;2 11; 3 -9; 4 -9; 5 19]
That is, if something in A doesn't exist in B(:,2), 2nd column of D should be -9.
If something in A exists in B(:,2), I want to put the corresponding row of 1st column of B in 2nd column of D.
I know how to do it with a mix of ismember and for and if. But I need a more elegant method which doesn't use "for" to speed it up.
Upvotes: 0
Views: 125
Reputation: 112699
For general A
:
A =[1;2;3;4;6]; % Note change in A
B= [10 1 ;11 2;19 5];
[aux, where] = ismember(A,B(:,2));
b_where = find(where>0);
D = [(1:length(A)).' repmat(-9,length(A),1)];
D(b_where,2) = B(where(b_where),1);
This gives
D = [ 1 10
2 11
3 -9
4 -9
5 -9 ]
Upvotes: 2
Reputation: 18484
Unless I'm missing something (or A
is not a vector of indices), this is actually much simpler and doesn't require ismember
or find
at all, just direct indexing:
D = [A zeros(length(A),1)-9];
D(B(:,2),2) = B(:,1)
which for your example matrices gives
D =
1 10
2 11
3 -9
4 -9
5 19
Upvotes: 4
Reputation: 17026
First create a temporary matrix:
tmp=[B; -9*ones(size(A(~ismember(A,B)))), A(~ismember(A,B))]
tmp =
10 1
11 2
19 5
-9 3
-9 4
Then use find
to obtain the first row index with a match to elements of A
in the second column of tmp
(there is always a match by design).
D=[A, arrayfun(@(x) tmp(find(tmp(:,2)==x,1,'first'),1),A)];
D =
1 10
2 11
3 -9
4 -9
5 19
As an alternative for the second step, you could simply sort tmp
based on its second column:
[~,I]=sort(tmp(:,2));
D=[tmp(I,2), tmp(I,1)]
D =
1 10
2 11
3 -9
4 -9
5 19
Upvotes: 0
Reputation: 12928
I am not sure how efficient this solution is, but it avoids using any loops so at least it would be a place to start:
D = [A -9*ones(size(A))]; % initialize your result
[tf, idx] = ismember(A, B(:,2)); % get indices of matching elements
idx(idx==0) = []; % trim the zeros
D(find(tf),2) = B(idx,1); % set the matching entries in D to the appropriate entries in B
disp(E)
You allocate your matrix ahead of time to save time later on (building up matrices dynamically is really slow in MATLAB). The ismember
call is returning the true-false vector tf
showing which elements of A
correspond to something in B
, as well as the associated index of what they correspond to in idx
. The problem with idx
is that it contains a zero any time ft
is zero, which is why we have the line idx(idx==0) = [];
to clear out these zeros. Finally, find(tf)
is used to get the indices associated with a match on the destination (rows of D
in this case), and we set the values at those indices equal to the corresponding value in B
that we want.
Upvotes: 1