use*_*235 1 matlab loops matrix nan
我有一系列具有正值的列,然后是NaN,例如:
12 16 10
11 13 9
8 10 7
7 6 5
4 1 4
2 NaN 2
NaN NaN 1
NaN NaN NaN
Run Code Online (Sandbox Code Playgroud)
如果是这个矩阵A
,那么可以使用以下方法找到每列中第一个NaN的(行)位置:sum(~isnan(A))
我现在想用零替换每个位置中的NaN,例如:
12 16 10
11 13 9
8 10 7
7 6 5
4 1 4
2 0 2
0 NaN 1
NaN NaN 0
Run Code Online (Sandbox Code Playgroud)
到目前为止,我尝试使用逻辑,索引和循环方法的组合失败了,创建了一个新的矩阵,其中所有NaN都为零,每个找到的行中的所有值都为零,或者只将第一列或最后一列中的NaN作为零.
实现这一目标的最佳方法是什么?谢谢.
方法#1
[m,n] = size(A) %// get size of input data
[v,ind] = max(isnan(A)) %// positions of first nans in each column
ind2 = bsxfun(@plus,ind,[0:n-1]*m) %// linear indices of those positions
A(ind2(v))=0 %// set values of all those positions to zero
Run Code Online (Sandbox Code Playgroud)
代码在示例输入上运行(稍微不同于有问题的示例) -
A (Input) =
12 16 10
11 13 9
8 10 7
7 6 5
4 1 4
2 NaN 2
4 NaN 1
1 NaN NaN
A (Output) =
12 16 10
11 13 9
8 10 7
7 6 5
4 1 4
2 0 2
4 NaN 1
1 NaN 0
Run Code Online (Sandbox Code Playgroud)
方法#2
如果您想使用您的sum(~isnan(A)
代码,那可能会形成另一种方法,但请注意,这假设NaN元素开始出现在列中时没有数值,因此#1方法更安全.这是方法#2的代码 -
[m,n] = size(A); %// get size of input data
ind = sum(~isnan(A))+1; %// positions of first nans in each column
v = ind<=m; %// position of valid ind values
ind2 = bsxfun(@plus,ind,[0:n-1]*m); %// linear indices of those positions
A(ind2(v))=0 %// set values of all those positions to zero
Run Code Online (Sandbox Code Playgroud)
Divakar的解决方案运行良好,但作为替代解决方案,您可以使用两个嵌套cumsum
来获取每行第一个NaN的掩码,并使用它将这些值重置为0;
A =
12 16 10
11 13 9
8 10 7
7 6 5
4 1 4
2 NaN 2
NaN 7 1
NaN NaN NaN
>>> A(cumsum(cumsum(isnan(A))) == 1) = 0
A =
12 16 10
11 13 9
8 10 7
7 6 5
4 1 4
2 0 2
0 7 1
NaN NaN 0
Run Code Online (Sandbox Code Playgroud)