Преобразовать вектор в логическую матрицу? - PullRequest
14 голосов
/ 08 ноября 2011

У меня есть вектор y длины n.y (i) является целым числом в 1..m.Существует ли более простой способ преобразования y в логическую матрицу nxm yy, где yy (i, j) = 1, если y (i) = j, но 0 в противном случае?Вот как я это делал:

% 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);

или

% 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);

Ответы [ 5 ]

12 голосов
/ 08 ноября 2011

Вы можете использовать bsxfun для этого

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

y преобразуется (при необходимости) в вектор-столбец, тогда как другой вектор является вектором строки.bsxfun неявно расширяет массивы m-by-1 и 1-n-n, так что результат становится m-by-n.

5 голосов
/ 08 ноября 2011

Если n * m достаточно велико (а m само по себе достаточно велико), неплохо было бы создать yy как разреженную матрицу.Ваш y вектор действительно является особым типом формата разреженной матрицы, но мы можем перевести его во встроенный формат разреженной матрицы, выполнив следующие действия.

yy = sparse(1:length(y), y, 1);

Это сохранит ваше хранилище на O (п).Это не принесет вам много пользы, если вы используете yy для большого количества индексации.Если это так, то лучше использовать исходную разреженную структуру (т. Е. y).

1 голос
/ 11 февраля 2017

Из машинного обучения на Coursera:

yy = eye(m)(y, :)

Для этого требуется, чтобы в списке был диапазон 1:m (как указано в ОП).Для нерегулярного списка, например [2 3 5], сделайте это

yy = eye(m)(:, [2 3 5])(y, :)

Примечание: не тестировалось на MATLAB.

1 голос
/ 06 ноября 2016

Небольшая модификация вашего метода:

% 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
0 голосов
/ 09 ноября 2018

В октаве вы можете написать:

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]
...