我在Matlab中有一个三维数组.第一个维度是时间,第二个维度是湿度,第三个维度是温度.如果温度值<0,我希望每个后续温度值都变为NaN.
例如,如果数组是:
>> sampl = randn(4,3,2)
sampl(:,:,1) =
0.79487 0.71017 -0.39167
0.51754 -1.3068 0.84166
0.49461 0.74159 0.082784
0.66393 1.4677 0.31467
sampl(:,:,2) =
0.78981 1.3096 1.0434
-0.80122 0.16037 -1.0682
-0.32565 -2.1182 -0.31723
0.28468 0.70708 1.4797
Run Code Online (Sandbox Code Playgroud)
将此转化为最有效的方法是什么:
sampl(:,:,1) =
0.79487 0.71017 NaN
0.51754 NaN NaN
0.49461 NaN NaN
0.66393 NaN NaN
sampl(:,:,2) =
0.78981 1.3096 1.0434
NaN 0.16037 NaN
NaN NaN NaN
NaN NaN NaN
Run Code Online (Sandbox Code Playgroud)
具体来说,对于特定切片,我们希望沿每列处理,并且一旦我们在一列中遇到负数,我们希望该位置与NaN该NaN值之后的同一列的所有行位置一样也是NaN.
另一种简单的方法是在原始矩阵中找到负数的位置,创建另一个矩阵,将这些值设置为NaN,cumsum沿着这个新矩阵的每个切片中的每一列的所有行调用一个或一个累积和,然后设置相应的此cumsum结果NaN中的位置在原始矩阵中获得最终结果:
>> out = sampl;
>> out(out < 0) = NaN;
>> out = cumsum(out);
>> sampl(isnan(out)) = NaN
sampl(:,:,1) =
0.7949 0.7102 NaN
0.5175 NaN NaN
0.4946 NaN NaN
0.6639 NaN NaN
sampl(:,:,2) =
0.7898 1.3096 1.0434
NaN 0.1604 NaN
NaN NaN NaN
NaN NaN NaN
Run Code Online (Sandbox Code Playgroud)
cumsum这里有用的原因是因为我们基本上会沿着它的行独立地检查每个列,并且在每个具有有效条目的列的所有行上累积,直到我们达到NaN列的值.在此值之后,cumsum将NaN在每个切片中的每个列中独立地成为后续值.因此,在我们点击NaN列中的第一个之后,无论我们遇到什么值(NaN或有效数字),结果cumsum仍然是NaN.NaN在我们遇到矩阵列中的第一个负数后,这会有效地传播值.最后一点是在该矩阵中找到那些位置并在原始矩阵中设置相应的位置NaN,从而给出我们的结果.
| 归档时间: |
|
| 查看次数: |
79 次 |
| 最近记录: |