mHelpMe
mHelpMe

Reputation: 6668

using ismember and indexing to get values from one vector to another

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

Answers (2)

Wolfie
Wolfie

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))

Getting ismember to work

We 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]

Using 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

Aero Engy
Aero Engy

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

Related Questions