Reputation: 6668
I have 2 vectors of Ids, lets call them a_id (10000 x 1) & b_id (4500 x 1).
I also have a vectors of numerical values, lets calls it b_num (4500 x 1). The values in b_num correspond to the id's in b_id.
Lastly I have a vector lets call it a_num which is (10000 x 1) which has no values in it. I want to populate it with the values from b_num where the id's match in a_id and b_id.
a_id b_id b_num
ADA BHN 2
PLB ADA 4
BHN LMK 3
LMK
So the result would look something like below,
a_id a_num
ADA 4
PLB 0
BHN 2
LMK 3
I am trying to use ismember but with out much joy.
a_num = NaN * ones(length(a_id(:, 1)), 1);
[found, pos] = ismember(a_id, b_id);
a_num(found(found~=0), 1) = b_num(pos(pos~=0), 1);
The result is
a_id a_num
ADA 4
PLB 2
BHN 3
LMK NaN
Upvotes: 1
Views: 74
Reputation: 30047
Firstly, you can use NaN
with input arguments the same as ones
, so initialise your a_num
using
a_num = NaN(size(a_id)); % Use size instead of length for clarity. length(x) = max(size(x))
ismember
to workWe can find all indices of a_id
within b_id
and assign like so
[bfound, idx] = ismember(a_id, b_id); % Find a_id members in b_id
a_num(bfound) = b_num(idx(bfound)); % Assign matched values
% output [4 NaN 2 3]
intersect
You can avoid some logical indexing by using the index arguments of intersect
. After initialising a_num
the same...
[~, a_idx, b_idx] = intersect(a_id, b_id); % indices of b in a and a in b
a_num(a_idx) = b_num(b_idx);
% output [4 NaN 2 3]
Upvotes: 2
Reputation: 3608
Is this what you want? ismember
seems to work fine. I think you were just miss using the found
part of your code (idxa
in mine). That is a logical array so you did not need to do this found(found~=0)
>> a_id ={ 'ADA' 'PLB' 'BHN' 'LMK'};
>> b_id = {'BHN' 'ADA' 'LMK'};
>> b_num = [2 4 3];
>> [idxa idxb] = ismember(a_id,b_id)
idxa =
1 0 1 1
idxb =
2 0 1 3
>> a_num = zeros(size(a_id));
>> a_num(idxa) = b_num(idxb(idxb~=0))
a_num =
4 0 2 3
Note: replace zeros()
with nan()
in the initialization of a_num
if you prefer that instead.
Upvotes: 1