2011-11-08 15 views
13

Ho un vettore y di lunghezza n. y (i) è un numero intero in 1..m. Esiste un modo più semplice per convertire y in una matrice logica n x m yy, dove yy (i, j) = 1 se y (i) = j, ma 0 altrimenti? Ecco come ho fatto esso:Converti vettore in matrice logica?

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

o

% 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

Ho trovato un altro modo ... non sono sicuro che sia meglio ... ma almeno si adatta su una riga: yy = repmat (y, 1, m) == repmat (1: m, n, 1); – notrick

+1

'bsxfun' è tra le funzioni Matlab multithreaded. Quindi è probabile che sia più veloce delle tue soluzioni. – Jonas

risposta

9

È possibile utilizzare bsxfun per questo

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

y si trasforma (se necessario) per una colonna-vettore, mentre l'altro vettore è un vettore di riga. bsxfun espande implicitamente gli array m-by-1 e 1-by-n in modo che il risultato diventi m-by-n.

5

Se n * m è sufficientemente grande (e m è, di per sé, sufficientemente grande), è una buona idea creare yy come matrice sparsa. Il tuo vettore è davvero un tipo speciale di formato di matrice sparsa, ma possiamo tradurlo nel formato di matrice sparse incorporato effettuando le seguenti operazioni.

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

Ciò manterrà lo spazio di archiviazione su O (n). Non ti farà molti privilegi se stai usando yy per un sacco di indicizzazione. In tal caso, è preferibile utilizzare la struttura originale sparsa (ad esempio,).

+0

+1 Definitivamente una migliore alternativa all'utilizzo di 'bsxfun'. –

1

una leggera modifica al tuo metodo:

% 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

Da Machine Learning on Coursera:

yy = eye(m)(y, :) 

Ciò richiede che la lista sia una gamma 1:m (come indicato OP). Per un elenco irregolare, come [2 3 5], fare questo

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

Nota: non testato su MATLAB.

+0

(Ma preferirei comunque la via di Jonas, molto carina). –

Problemi correlati