Reputation: 441
e.g
I have a vector:
a=[4 4 15 15 9 9 7 7];
how do I efficiently replace all 4s into 1s, all 15s into 2s, 9s into 3s and 7s into 4s? instead of coding repeatly:
a(a==4)=1; a(a==15)=2; a(a==9)=3; a(a==7)=4; ....
in the case I have too many number to be replaced?
Thank you very much!
Upvotes: 4
Views: 3188
Reputation: 221504
There is a MATLAB built-in changem (Substitute values in data array)
in Mapping Toolbox
for exactly this purpose -
changem(input_arr,newvals,oldvals)
Sample run -
>> a
a =
4 4 15 15 9 9 7 7
>> oldvals = [4,15,9,7];
>> newvals = [1, 2,3,4];
>> changem(a,newvals,oldvals)
ans =
1 1 2 2 3 3 4 4
If you don't have access to the Mapping Toolbox
or if you are looking for a vectorized solution, I would like to suggest Vectorized implementation of CHANGEM with bsxfun, max
.
Upvotes: 3
Reputation: 9696
If you really want an "abitrary" replacement, where there's no direct relation between original and replaced value, you could use ismember
:
>> map = [4 1; 15 2; 9 3; 7 4];
>> [~, loc] = ismember(a, map(:,1));
>> a(:) = map(loc,2)
a =
1 1 2 2 3 3 4 4
Depending on what your larger context is, you might want to check unique
, as it seems your doing something similar. In this case for example:
>> [~,~,a2] = unique(a, 'stable')
a2 =
1 1 2 2 3 3 4 4
Which works for your example and doesn't require you to construct a map as it makes it's own based on order of appearance.
Or if your version of Matlab predates the 'stable'
property of unique` then
>> [~,~,a2] = unique(a)
a2 =
1 1 4 4 3 3 2 2
Which is similar to your replacement, though these numbers refer to the index of each element in the sorted list of distinct elements in a
, while your example seems to use the unsorted index - though this might just be an arbitrary choice for your example.
Upvotes: 8