Reputation: 227
I have a vector y of length n. y(i) is an integer in 1..m. Is there a simpler way to convert y into an n x m logical matrix yy, where yy(i, j) = 1 if y(i) = j, but 0 otherwise? Here's how I've been doing it:
% If m is known (m = 3 here), you could write it out all at once
yy = [y == 1; y== 2; y == 3];
yy = reshape(yy, n, 3);
or
% if m is not known ahead of time
yy = [ y == 1 ];
for i = 2:m;
yy = [ yy; y == i ];
end
yy = reshape(yy, n, m);
Upvotes: 14
Views: 4164
Reputation: 97
In octave you can write:
yy = y' == (1:m); % or y == (1:m)' for transposed
[1 2 1 3 2] == [1 2 3]' % = [1 0 1 0 0; 0 1 0 0 1; 0 0 0 1 0]
Upvotes: 1
Reputation: 9938
From Machine Learning on Coursera:
yy = eye(m)(y, :)
This requires that the list be a range 1:m
(as OP stated). For an irregular list, like [2 3 5]
, do this
yy = eye(m)(:, [2 3 5])(y, :)
Note: not tested on MATLAB.
Upvotes: 1
Reputation: 21
A slight modification to your method:
% A n-dimensional vector y, with values in some range 1..m
m = 4;
n = 7;
y = randi([1 m], n, 1);
% Preallocating a n by m matrix of zeros
nXm = zeros(n, m);
% In each pass of this loop a single column of nXm is updated, where
% for each column index j in nXm, if y(i) = j then nXm(i,j) = 1
for j = 1:m;
nXm(:,j) = (y == j);
end
Upvotes: 2
Reputation: 18091
If n*m is sufficiently large (and m is, by itself, sufficiently large), it is a good idea to create yy
as a sparse matrix. Your y
vector is really a special type of sparse matrix format, but we can translate it into the built-in sparse matrix format by doing the following.
yy = sparse(1:length(y), y, 1);
This will keep your storage to O(n). It is not going to be doing you a lot of favors if you are using yy
for a lot of indexing. If that is the case you are better off using your original sparse structure (i.e., y
).
Upvotes: 5