notrick
notrick

Reputation: 227

Convert vector into logical matrix?

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

Answers (5)

Pier Bezuhoff
Pier Bezuhoff

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

Franklin Yu
Franklin Yu

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

leabstrait
leabstrait

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

David Alber
David Alber

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

Jonas
Jonas

Reputation: 74930

You can use bsxfun for this

yy = bsxfun(@eq,y(:),[1,2,3])

y is transformed (if necessary) to a column-vector, while the other vector is a row vector. bsxfun implicitly expands the m-by-1 and 1-by-n arrays so that the result becomes m-by-n.

Upvotes: 12

Related Questions