Lookup values in other matrix

1 view (last 30 days)
Fischer Zheng
Fischer Zheng on 15 Sep 2015
Edited: dpb on 16 Sep 2015
I have two very large vectors of the same size:
Vector 1 contains a list of type
Type ("Math","Chem","Bio")
["Math" "Chem" "Bio" "Chem" "Chem" "Math" ...]
Vector 2 contains a different list of types
Type ("Baseball","Tennis","Soccer")
["Baseball" "Tennis" "Soccer" "Tennis" "Tennis" "Baseball" ...]
I have another small matrix with numeric values associated with each combination of the two types:
"Math" "Baseball" 5
"Math" "Tennis" 8
"Chem" "Baseball" 16
.....
I would like to create a new vector to lookup base on the matrix for the numeric value. What would be the vectorized way to deal with this situation? Seems like a very common task, but I couldn't figure it out.
Thanks in advance, Fischer

Accepted Answer

dpb
dpb on 15 Sep 2015
Edited: dpb on 16 Sep 2015
>> v1={'Math'; 'Chem'; 'Bio'; 'Chem'; 'Chem'; 'Math'};
>> v2={'Baseball' 'Tennis' 'Soccer' 'Tennis' 'Tennis' 'Baseball'}.';
>> A={'Math' 'Baseball' 5;
'Math' 'Tennis' 8;
'Chem' 'Baseball' 16};
>> A(ismember([char(A(:,1)) char(A(:,2))], ...
[char(v1) char(v2)],'rows'),:)
ans =
'Math' 'Baseball' [5]
>>
ADDENDUM Per comment below, reorder; use alternate return index--
>> [~,ib]=ismember([char(v1) char(v2)], ...
[char(A(:,1)) char(A(:,2))],'rows')
ib =
1 0 0 0 0 1
>> for i=1:length(ib)
if ib(i)
A(ib(i),:)
else
disp('?')
end
end
ans =
'Math' 'Baseball' [5]
?
?
?
?
ans =
'Math' 'Baseball' [5]
>>
ADDENDUM 2 To clarify above remark, built full table with arbitrary (but satisfy the previous partial values) assignments for the numerical values as follows--
>> u1=unique(v1); % unique subjects
u1 =
'Bio'
'Chem'
'Math'
>> a=[6 12 1]; % corresponding values
>> u2=unique(v2) % ditto for sports
u2 =
'Baseball'
'Soccer'
'Tennis'
>> s=[4 6 7];
>> k=0; % now build the table
for i=1:3,for j=1:3,
k=k+1;
A(k,:)={u1{i} u2{j} a(i)+s(j)};
end,end
>> A
A =
'Bio' 'Baseball' [10]
'Bio' 'Soccer' [12]
'Bio' 'Tennis' [13]
'Chem' 'Baseball' [16]
'Chem' 'Soccer' [18]
'Chem' 'Tennis' [19]
'Math' 'Baseball' [ 5]
'Math' 'Soccer' [ 7]
'Math' 'Tennis' [ 8]
>> [~,ib]=ismember([char(v1) char(v2)], ...
[char(A(:,1)) char(A(:,2))],'rows');
>> A(ib,:)
ans =
'Math' 'Baseball' [ 5]
'Chem' 'Tennis' [19]
'Bio' 'Soccer' [12]
'Chem' 'Tennis' [19]
'Chem' 'Tennis' [19]
'Math' 'Baseball' [ 5]
>>
  4 Comments
Fischer Zheng
Fischer Zheng on 16 Sep 2015
With your approach, when lookup is unique, it is working fine. If lookup table is not unique, this will run into problems. For my purpose, this is good enough.
Thanks,
dpb
dpb on 16 Sep 2015
Edited: dpb on 16 Sep 2015
Well, yeah, that was part of the problem description. If it isn't, that's a fish of another kettle...
I'd note it'd probably be simpler also if you kept or made a hash key from the two variables as well as in the lookup table to avoid the need to mush the two together and using the 'rows' flag to get around the storage issues of cell arrays being needed for the disparate data types and the length issues in concatenating character data.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!