根据部分填充的向量形成“部分”单位矩阵
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了根据部分填充的向量形成“部分”单位矩阵相关的知识,希望对你有一定的参考价值。
我正在按照下面描述的方案在MATLAB中使用向量形成矩阵:
给定的是包含任意顺序的1和0的向量x
,例如,
x = [0 1 1 0 1];
由此,我想形成一个矩阵Y
,描述如下:
Y
有m
行,其中m
是x
中的数量(这里:3
)。Y
的每一行都填充了k
条目中的一行,其中k
是矢量x
中的一个位置(此处:k = 2,3,5
)- 对于上面的示例
x
,这将导致:Y = [0 1 0 0 0; 0 0 1 0 0; 0 0 0 0 1]
这与已消除其(x=0
)行的单位矩阵相同。
我目前通过以下代码实现此目的:
x = [0,1,1,0,1]; %example from above
m = sum(x==1);
Y = zeros(m,numel(x));
p = 1;
for n = 1:numel(x)
if x(n) == 1
Y(p,n) = 1;
p = p+1;
end
end
它有效,但我对它不满意,因为它似乎相当低效和不优雅。任何更平滑的实现的想法,可能使用一些矩阵乘法等,是受欢迎的。
答案
以下是一些单行替代方案:
- 使用
sparse
:Y = full(sparse(1:nnz(x), find(x), 1));
- 类似但与
accumarray
:Y = accumarray([(1:nnz(x)).' find(x(:))], 1);
- 使用
eye
和索引。这假设Y
以前未定义:Y(:,logical(x)) = eye(nnz(x));
另一答案
使用find
获取x
中的索引,这些索引也是Y
中的列的下标。通过Y
找到矢量adding的所有元素的x
行数。使用这些来初始化Y
作为zero matrix。现在找到使用sub2ind
放置1s的线性指数。 Use these indices将Y
的元素改为1。
cols = find(x);
noofones = sum(x);
Y = zeros(noofones, size(x,2));
Y(sub2ind(size(Y), 1:noofones, cols)) = 1;
另一答案
这是使用矩阵乘法的替代方法:
x = [0,1,1,0,1];
I = eye(numel(x));
% construct identity matrix with zero rows
Y = I .* x; % uses implicit expansion from 2016b or later
Y = Y(logical(x), :); % take only non-zero rows of Y
结果:
Y =
0 1 0 0 0
0 0 1 0 0
0 0 0 0 1
感谢@ SardarUsama关于简化代码的评论。
另一答案
谢谢大家的好选择!我尝试了所有的解决方案,平均执行时间超过1e4执行随机(1000条目)x向量。结果如下:
- (7.3e-4秒)
full(sparse(1:nnz(x), find(x), 1));
- (7.5e-4秒)
cols = find(x); noofones = sum(x); Y = zeros(noofones, size(x,2)); Y(sub2ind(size(Y), 1:noofones, cols)) = 1;
- (7.7e-4秒)
Y = accumarray([(1:nnz(x)).' find(x(:))], 1);
- (1.7e-3秒)
I = speye(numel(x)); Y = I .* x; Y = full(Y(logical(x), :));
- (3.1e-3秒)
Y(:,logical(x)) = eye(nnz(x));
另一答案
从你的评论“这与一个单位矩阵相同,它消除了第(x = 0)行。”,你也可以明确地生成它:
Y = eye(length(x));
Y(x==0, :) = [];
长x
非常慢的选项,但它的full(sparse(...
比我的计算机上有10个元素的x
略快。
以上是关于根据部分填充的向量形成“部分”单位矩阵的主要内容,如果未能解决你的问题,请参考以下文章
matlab对矩阵/向量的常用操作(拼接矩阵向量逆序改变矩阵形状求行阶梯形矩阵提取矩阵的一部分等)