2011-11-08 3 views
6

J'ai un y de taille 5000,1 (matrice), qui contient des entiers compris entre 1 et 10. Je veux étendre ces indices en un vecteur de 1 sur 10. À savoir, y contient 1,2,3 ... et je veux qu'il « étendre » à:Représentation Matlab/Octave 1-of-K

1 0 0 0 0 0 0 0 0 0 
0 1 0 0 0 0 0 0 0 0 
0 0 1 0 0 0 0 0 0 0 

Quelle est la meilleure façon de le faire?

J'ai essayé:

Y = zeros(5000,10); Y(y) = 1; 

mais cela n'a pas fonctionné.

Il travaille pour des vecteurs bien:

si y = [2 5 7] et Y = zeros(1,10), puis Y(y) = [0 1 0 0 1 0 1 0 0 0].

+0

double possible de [Création d'indicateurs Matrice] (http://stackoverflow.com/questions/6150174/creating-indicator-matrix) – Amro

Répondre

6
n=5 
Y = ceil(10*rand(n,1)) 
Yexp = zeros(n,10); 
Yexp(sub2ind(size(Yexp),1:n,Y')) = 1 

Aussi, pensez à utiliser clairsemée, comme dans: Creating Indicator Matrix.

+0

Est-ce ther e mérites/démérites relatifs à bsxfun v. sub2ind? – Frank

+0

@Frank: c'est basé sur l'indexation, la mienne consiste à faire des comparaisons d'égalité ... Serait intéressant de voir comment ils se comparent en termes de performance – Amro

+0

J'ai vérifié la performance. La solution sub2ind est légèrement plus rapide que la solution bsxfun. – cyborg

-2

Je pense que vous voulez dire:

y = [2 5 7]; 
Y = zeros(5000,10); 
Y(:,y) = 1; 

Après la modification de la question, il devrait être plutôt:

y = [2,5,7,9,1,4,5,7,8,9....]; //(size (1,5000)) 
for i = 1:5000 
    Y(i,y(i)) = 1; 
end 
+0

Cela va mettre les colonnes entières y à 1. – cyborg

+0

Je voulais éviter d'écrire la boucle, ce qui est la solution la plus évidente :-) – Frank

+0

question n'était pas très clair jusqu'à ce qu'Amro l'édite :), assurez-vous d'accepter l'autre gars répondre – Smash

6

Considérez ce qui suit:

y = randi([1 10],[5 1]);  %# vector of 5 numbers in the range [1,10] 
yy = bsxfun(@eq, y, 1:10)'; %# 1-of-10 encoding 

Exemple:

>> y' 
ans = 
    8  8  4  7  2 
>> yy 
yy = 
    0  0  0  0  0 
    0  0  0  0  1 
    0  0  0  0  0 
    0  0  1  0  0 
    0  0  0  0  0 
    0  0  0  0  0 
    0  0  0  1  0 
    1  1  0  0  0 
    0  0  0  0  0 
    0  0  0  0  0 
+0

Voilà ce que je cherche, donner ou prendre une transposition :-) Merci! – Frank

+0

@Frank: Je crois aussi que la Statistics Toolbox a une fonction assez similaire [DUMMYVAR] (http://www.mathworks.com/help/toolbox/stats/dummyvar.html) – Amro

2

Bien que rares peut être plus rapide et économiser de la mémoire, une réponse impliquant les yeux() serait plus élégant que il est plus rapide qu'une boucle et il a été introduit au cours de la conférence d'octave de cette classe

Voici un exemple pour 1 à 4

V = [3;2;1;4]; 
I = eye(4); 
Vk = I(V, :); 
+0

Ce qui fonctionne pour moi est eye (K) (V, :) qui est similaire au vôtre mais condense les lignes 2 et 3 en une seule ligne. Plus utile cependant, K est le nombre de classes possibles, pas réellement les classes présentes, donc par exemple s'il y avait 10 résultats possibles dont 4 étaient réellement présents, cela fonctionnerait plus correctement et plus sûrement. –

0

Vous pouvez essayer des opérations de cellfun:

function vector = onehot(vector,decimal) 
    vector(decimal)=1; 
end 
aa=zeros(10,2); 
dec=[5,6]; 
%split into columns 
C=num2cell(aa,1); 
D=num2cell(dec,1); 
onehotmat=cellfun("onehot",C,D,"UniformOutput",false); 
output=cell2mat(onehotmat);