2011-11-08 4 views
13

J'ai un vecteur y de longueur n. y (i) est un nombre entier dans 1..m. Existe-t-il un moyen plus simple de convertir y en une matrice logique n x m yy, où yy (i, j) = 1 si y (i) = j, mais 0 sinon? Voici comment je l'ai fait:Convertir un vecteur en matrice logique?

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

ou

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

J'ai trouvé un autre moyen ... je ne sais pas si c'est mieux ... mais au moins ça correspond à une ligne: yy = repmat (y, 1, m) == repmat (1: m, n, 1) – notrick

+1

'bsxfun' fait partie des fonctions Matlab multithread. Ainsi, il est susceptible d'être plus rapide que vos solutions. – Jonas

Répondre

9

Vous pouvez utiliser bsxfun pour cette

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

y est transformé (si nécessaire) à une colonne vecteur, tandis que l'autre vecteur est un vecteur ligne. bsxfun étend implicitement les tableaux m-by-1 et 1-by-n de sorte que le résultat devienne m-by-n.

5

Si n * m est suffisamment grand (et m est, en soi, suffisamment grand), il est préférable de créer yy en tant que matrice creuse. Votre vecteur y est vraiment un type spécial de format de matrice creuse, mais nous pouvons le traduire dans le format matriciel sparse intégré en procédant comme suit.

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

Cela permettra de conserver votre stockage à O (n). Il ne va pas vous faire beaucoup de faveurs si vous utilisez yy pour beaucoup d'indexation. Si tel est le cas, il vaut mieux utiliser votre structure clairsemée d'origine (c'est-à-dire, y).

+0

+1 Certainement une meilleure alternative à l'utilisation de 'bsxfun'. –

1

Une légère modification à votre méthode:

% 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 
1

de l'apprentissage machine sur Coursera:

yy = eye(m)(y, :) 

Cela exige que la liste soit une gamme 1:m (OP comme indiqué). Pour une liste irrégulière, comme [2 3 5], faire

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

Note: non testé sur Matlab.

+0

(Mais je préférerais toujours le chemin de @ Jonas, très soigné.) –

Questions connexes