我目前正在按照以下方案从MATLAB中的向量形成矩阵:
Given是向量x
,包含任意顺序的一和零,例如
x = [0 1 1 0 1];
由此,我想形成一个矩阵Y
,其描述如下:
Y
具有m
行,其中m
是x
中的行数(此处为3
)。Y
的每一行在第k
项处填充一个,其中k
是向量x
中一个的位置(此处:{ {1}})对于上面的示例k = 2,3,5
,这将导致:
x
这与一个单位矩阵相同,后者消除了第(Y = [0 1 0 0 0;
0 0 1 0 0;
0 0 0 0 1]
)行。
我目前正在通过以下代码实现这一目标:
x=0
它有效,但是我有点不满意,因为它看起来效率低下且不够优雅。欢迎提出任何更平滑实现的想法,也许使用一些矩阵乘法。
答案 0 :(得分:5)
以下是一些单行替代方法:
使用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));
答案 1 :(得分:4)
使用find
获得x
中1的索引,它们也是Y
中1的列下标。通过adding找到向量Y
的所有元素的x
行数。使用这些将Y
初始化为zero matrix。现在,使用sub2ind
找到放置1的线性索引。 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;
答案 2 :(得分:4)
这是使用矩阵乘法的另一种选择:
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的注释,它简化了代码。
答案 3 :(得分:1)
感谢大家提供不错的选择!我尝试了所有解决方案,并针对随机(1000个条目)x向量执行了1e4次执行的平均执行时间。结果如下:
server <- function(input, output) {
observe({
file1=input$file1
if (is.null(file1)){
return(NULL)
}
df<-read.csv(file1$datapath)
df$FAIL<-ifelse(df$OPERATION_STATUS %in% "FAIL",1,0)
output$env<-renderPlot({
e <- df[which(df$CATEGORY %in% "OSV-ENVIRONMENT" & df$FAIL == 1),]
p <- ggplot(e, aes(DATE, CRIT_CODE, color=as.factor(FAIL))) +
geom_point(size=3) +
labs(title="Environment Fails by Date") +
theme_light() +
theme(plot.title=element_text(hjust=0.5))
print(p)
})
})
full(sparse(1:nnz(x), find(x), 1));
cols = find(x);
noofones = sum(x);
Y = zeros(noofones, size(x,2));
Y(sub2ind(size(Y), 1:noofones, cols)) = 1;
Y = accumarray([(1:nnz(x)).' find(x(:))], 1);
I = speye(numel(x));
Y = I .* x;
Y = full(Y(logical(x), :));
答案 4 :(得分:1)
根据您的评论“这与一个单位矩阵相同,其中消除了第(x = 0)行。”那么,您也可以像这样显式生成它:
Y = eye(length(x));
Y(x==0, :) = [];
长x
的选项非常慢,但是在计算机上有10个元素的情况下,full(sparse(...
的运行速度比x
快。