2

For neural networking, I would like to represent a column vector y = [1;2;3] in a matrix like so:

y = [1 0 0; 0 1 0; 0 0 1] 

My vector y is very large, and so hardcoding is not an option. Also, I would like to avoid using for-loops.

What I did so far:

y1 =[y; zeros(1,length(y)) ;zeros(1,length(y))] % add two rows with zeros in orde to give y the right format idx = find(y1(1,:) == 2); % find all the columns containing a 2 y1(:,idx(1):idx(end)) = y1(:,[0;1;0]); % this does not work because now I am comparing a matrix with a vector 

I also tried this:

y1( y1 == [2;0;0] )=[0;1;0]; % This of course does not work 

Is there a way to specify I want to compare columns in y1 == [2;0;0], or is there another way to solve this?

0

4 Answers 4

8

From the context of your question, you wish to find a matrix where each column is an identity vector. For an identity vector, each column in this matrix is a non-zero vector where 1 is set in the position of the vector denoted by each position of y and 0 otherwise. Therefore, let's say we had the following example:

y = [1 5 4 3] 

You would have y_out as the final matrix, which is:

y_out = 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 

There are several ways to do this. The easiest one would be to declare the identity matrix with eye, then let y pick out those columns that you want from this matrix and place them as columns into your final matrix. If y had all unique values, then we would simply be rearranging the columns of this identity matrix based on y. As such:

y_out = eye(max(y)); y_out = y_out(:,y) y_out = 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 

Another way would be to declare a sparse matrix, where each row index is simply those elements from y and each column index is increasing from 1 up to as many elements as we have y:

y_out = sparse(y, 1:numel(y), 1, max(y), numel(y)); y_out = full(y_out) y_out = 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 

One more way would be to use sub2ind to find linear indices into your matrix, then access those elements and set them to 1. Therefore:

ind = sub2ind([max(y) numel(y)], y, 1:numel(y)); y_out = zeros(max(y), numel(y)); y_out(ind) = 1 y_out = 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 
Sign up to request clarification or add additional context in comments.

3 Comments

Please consider editing the title of the question; it is not relevant to the topics explained here.
@erfan I haven't changed it as this is the title I am accustomed to for this question and it was asked almost 2 years ago. Everyone I know who uses this as a duplicate since that point uses this as the question title when searching for this duplicate. However, if you have a suggestion on what title to use, I would certainly be welcome to them.
I actually could not come up with a good replacement. I just found it impossible for a new user to find this post from the title. But I think it is not very necessary, since if a similar concept is discussed in a duplicate with a better chosen title, that would eventually lead people to this post.
2

This works even if y has "missing" values:

n = numel(y); y_matrix = zeros(n, max(y)); y_matrix((1:n) + (y-1)*n) = 1; 

Example:

y = [1 5 3 2]; 

gives

y_matrix = 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 

6 Comments

Very nice :) Much faster than sub2ind as you're computing the indices directly.
Minor note: You might want to transpose the result because each result in the output is meant to be a column vector... then again, I'm not quite sure what the OP wants!
A nice solution too! I figured I had to transpose the result (but that was the case in rayryeng's solution as well).
So @rayryeng was right in his suggestion. In fact, I couldn't tell from your question exactly what you wanted
@LuisMendo - Neither could I, but given that the question had the word "columns", that was my best guess.
|
2

You can use bsxfun:

y_out = bsxfun(@eq, (1:max(y)).', y); 

Comments

1

Not as efficient as the @rayryeng's answer but this might also help,

Also if there are repeated values in y this code works fine.

a = [1 2 3 2 5 7 6 8]; [X,Y] = meshgrid(a,1 : length(a)); A = X == Y; A = 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.