Kristada673
Kristada673

Reputation: 3744

What's the most concise way to replace items in a vector by items in another vector?

Say, I have a mxn matrix M, whose column 1 contains values like -1, 0, 4, 12, 27, ..., and they can occur multiple times. These are not sequential numbers, so I would like to replace wherever they occur in M with corresponding natural numbers (i.e., the smallest value in the column should be replaced by 1, the second smallest by 2, the third smallest by 3, and so on).

I can easily do this using a for loop running over the length of the column, and writing the replacement condition for each unique value in the column:

for i=1:size(unique(M(:,1)),1)
    M(M(:,1)==-1)=1;
    M(M(:,1)==0)=2;
    M(M(:,1)==4)=3;
    M(M(:,1)==12)=4;
    M(M(:,1)==27)=5;
    ...
    ...
    ...
end

However, this can get to be tedious if the number of unique elements in the column is large. I would like to know a better, more concise way of doing this, utilizing MATLAB vectorization. So, I tried to use the changem function to replace all values in the original data by natural numbers:

changem(M(:,1), unique(M(:,1))', [1:1:numel(unique(M(:,1)))]);

But this doesn't work. It only replaces the first 2 or 3 unique numbers in M. Why?

EDIT: Sample example. Say the first few rows of my matrix M are as follows:

91  620011  sunday  1.43309E+12     
92  620194  sunday  1.43309E+12 25.0048276  121.3041219
91  620072  sunday  1433087996  25.038848   121.455705
91  620177  sunday  1.43309E+12     
91  620268  sunday  1.43309E+12 24.79293518 120.9506341
92  620266  sunday  1433087991      
107 620092  sunday  1.43309E+12 24.86219998 120.9648107
1   36581192    sunday  1433087990      
91  620268  sunday  1.43309E+12     
91  619897  sunday  1.43309E+12 24.9161251  121.2068644

Then, assuming 0 is the smallest element, 91 is the 10th smallest element, 92 is the 11th smallest element, and 107 is the 15th smallest element, I want the matrix to become this:

10  620011  sunday  1.43309E+12     
11  620194  sunday  1.43309E+12 25.0048276  121.3041219
10  620072  sunday  1433087996  25.038848   121.455705
10  620177  sunday  1.43309E+12     
10  620268  sunday  1.43309E+12 24.79293518 120.9506341
11  620266  sunday  1433087991      
15  620092  sunday  1.43309E+12 24.86219998 120.9648107
1   36581192    sunday  1433087990      
10  620268  sunday  1.43309E+12     
10  619897  sunday  1.43309E+12 24.9161251  121.2068644

Upvotes: 0

Views: 38

Answers (2)

Dan
Dan

Reputation: 45741

The third output of unique should do it for you:

[~,~,M(:,1)] = unique(M(:,1))

Upvotes: 1

marco wassmer
marco wassmer

Reputation: 421

Edit:

First you make one big list:

B = reshape(M,[],m*n)

Then sort it:

[~,key] = sort(B)

and make a Matrix:

_M = reshape(key,size(M))

Cant test it right now, sorry


If you use [B,key] = sort(___), key is the vector you want

Upvotes: 0

Related Questions