6

On Octave I'm trying to unpack a vector in the format:

y = [ 1  
      2  
      4  
      1 
      3 ]

I want to return a matrix of dimension ( rows(y) x max value(y) ), where for each row I have a 1 in the column of the original digits value, and a zero everywhere else, i.e. for the example above

y01 = [ 1 0 0 0
        0 1 0 0
        0 0 0 1
        1 0 0 0
        0 0 1 0 ]

so far I have

y01 = zeros( m, num_labels );
for i = 1:m
    for j = 1:num_labels
        y01(i,j) = (y(i) == j);
    end
end

which works, but is going get slow for bigger matrices, and seems inefficient because it is cycling through every single value even though the majority aren't changing.

I found this for R on another thread:

f3 <- function(vec) {
    U <- sort(unique(vec))
    M <- matrix(0, nrow = length(vec), 
          ncol = length(U), 
          dimnames = list(NULL, U))
    M[cbind(seq_len(length(vec)), match(vec, U))] <- 1L
    M
}

but I don't know R and I'm not sure if/how the solution ports to octave.

Thanks for any suggestions!

Community
  • 1
  • 1
ralph346526
  • 338
  • 3
  • 12

4 Answers4

7

Use a sparse matrix (which also saves a lot of memory) which can be used in further calculations as usual:

y = [1; 2; 4; 1; 3]
y01 = sparse (1:rows (y), y, 1)

if you really want a full matrix then use "full":

full (y01)
ans =
1   0   0   0
0   1   0   0
0   0   0   1
1   0   0   0
0   0   1   0
Andy
  • 7,931
  • 4
  • 25
  • 45
1

Sparse is a more efficient way to do this when the matrix is big. If your dimension of the result is not very high, you can try this:

y = [1; 2; 4; 1; 3]
I = eye(max(y));
y01 = I(y,:)

The result is same as full(sparse(...)).

y01 =

   1   0   0   0
   0   1   0   0
   0   0   0   1
   1   0   0   0
   0   0   1   0
Leon.Z
  • 61
  • 3
1
% Vector y to Matrix Y
Y = zeros(m, num_labels);

% Loop through each row
for i = 1:m
    % Use the value of y as an index; set the value matching index to 1
    Y(i,y(i)) = 1;
end
Darren Murphy
  • 1,076
  • 14
  • 12
0

Another possibility is:

y = [1; 2; 4; 1; 3]
classes = unique(y)(:)
num_labels = length(classes)
y01=[1:num_labels] == y 

With the following detailed printout:

y =    
   1
   2
   4
   1
   3

classes =    
   1
   2
   3
   4

num_labels =  4
y01 =

  1  0  0  0
  0  1  0  0
  0  0  0  1
  1  0  0  0
  0  0  1  0
Nakx
  • 1,460
  • 1
  • 23
  • 32