2011-11-08 138 views
13

我有一个长度为n的向量y。 y(i)是1..m中的整数。是否有更简单的方法将y转换为n x m逻辑矩阵yy,其中如果y(i)= j,则yy(i,j)= 1,否则为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); 
+0

我找到了另一种方式...不知道这是否更好...但至少它适合一行:yy = repmat(y,1,m)== repmat(1:m,n,1 ); – notrick

+1

'bsxfun'是多线程的Matlab函数。因此它可能比您的解决方案更快。 – Jonas

回答

9

您可以使用bsxfun这个

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

y转换(如有必要)的列向量,而另一个向量是一个行向量。 bsxfun隐式扩展m乘1和1乘n数组,以便结果变成m乘n。

5

如果n * m足够大(并且m本身足够大),则创建yy作为稀疏矩阵是一个好主意。您的y矢量实际上是一种特殊类型的稀疏矩阵格式,但我们可以通过执行以下操作将其转换为内置稀疏矩阵格式。

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

这将让您的存储来为O(n)。如果你使用yy进行大量索引,它不会对你有很大的帮助。如果是这种情况,最好使用原始稀疏结构(即y)。

+0

+1绝对是使用'bsxfun'的更好选择。 –

1

少许修改你的方法:

% 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

机器学习在Coursera:

yy = eye(m)(y, :) 

这要求该列表是一个范围1:m(如OP说明)。对于不规则列表,像[2 3 5],做到这一点

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

注:MATLAB未经测试。

+0

(但我仍然更喜欢@乔纳斯的方式,非常整洁。) –