将向量转换为逻辑矩阵?

14

我有一个长度为n的向量y。y(i)是1到m之间的整数。是否有一种更简单的方法将y转换为n x m的逻辑矩阵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);

我找到了另一种方法...不确定这是否更好...但至少它适合一行代码:yy = repmat(y,1,m) == repmat(1:m, n, 1); - notrick
1
bsxfun 是 Matlab 中的多线程函数之一。因此,它很可能比您的解决方案更快。 - Jonas
5个回答

12

你可以使用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)。

2
您的方法稍作修改:

% 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上测试。

但我仍然更喜欢@Jonas的方式,非常整洁。 - Franklin Yu

1
在Octave中,您可以编写以下内容:

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]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接