gpt4 book ai didi

matlab - 以完全矢量化的方式用前一个元素逐行或逐列替换矩阵中的零(或 NAN)

转载 作者:太空宇宙 更新时间:2023-11-03 20:04:55 25 4
gpt4 key购买 nike

我需要用前一个元素按行替换矩阵中的零(或 NaN),所以基本上我需要这个矩阵 X

[0,1,2,2,1,0;  
5,6,3,0,0,2;
0,0,1,1,0,1]

变成这样:

[0,1,2,2,1,1;  
5,6,3,3,3,2;
0,0,1,1,1,1],

请注意,如果第一行元素为零,它将保持原样。

我知道这已经以向量化的方式解决了单个行或列向量,这是最好的方法之一:

id = find(X);         
X(id(2:end)) = diff(X(id));
Y = cumsum(X)

问题是 Matlab/Octave 中矩阵的索引是连续的,并且按列递增,因此它适用于单个行或列,但不能应用相同的概念,但需要用多行进行修改,因为每个行raw/column 重新开始,必须被视为独立的。我已经尽了最大努力并搜索了整个谷歌,但找不到出路。如果我在循环中应用同样的想法,它会变得太慢,因为我的矩阵至少包含 3000 行。谁能帮我解决这个问题?

最佳答案

每行中零被隔离的特殊情况

您可以使用 find 的双输出版本来做到这一点在除第一列之外的所有列中找到零和 NaN,然后​​使用 linear indexing用它们的行前值填充这些条目:

[ii jj] = find( (X(:,2:end)==0) | isnan(X(:,2:end)) );
X(ii+jj*size(X,1)) = X(ii+(jj-1)*size(X,1));

一般情况(每行允许连续零)

X(isnan(X)) = 0; %// handle NaN's and zeros in a unified way
aux = repmat(2.^(1:size(X,2)), size(X,1), 1) .* ...
[ones(size(X,1),1) logical(X(:,2:end))]; %// positive powers of 2 or 0
col = floor(log2(cumsum(aux,2))); %// col index
ind = bsxfun(@plus, (col-1)*size(X,1), (1:size(X,1)).'); %'// linear index
Y = X(ind);

诀窍是利用矩阵aux,如果X对应的条目为0且其列号大于1,则包含0;否则包含 2 提升到列号。因此,对该矩阵逐行应用 cumsum,取 log2 并向下舍入(矩阵 col)给出最右边的非零条目的列索引直到当前条目,对于每一行(所以这是一种按行的“累积最大”函数。)它只剩下从列号转换为线性索引(使用 bsxfun ;也可以使用 sub2ind) 并用它来索引 X

这仅对中等大小的 X 有效。对于大尺寸,代码使用的 2 的幂很快接近 realmax 并且导致不正确的索引。

例子:

X =
0 1 2 2 1 0 0
5 6 3 0 0 2 3
1 1 1 1 0 1 1

给予

>> Y
Y =
0 1 2 2 1 1 1
5 6 3 3 3 2 3
1 1 1 1 1 1 1

关于matlab - 以完全矢量化的方式用前一个元素逐行或逐列替换矩阵中的零(或 NAN),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21068256/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com