在第一个否定之后将元素转换为NaN

sie*_*gel 4 matlab

我在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.

ray*_*ica 7

另一种简单的方法是在原始矩阵中找到负数的位置,创建另一个矩阵,将这些值设置为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列的值.在此值之后,cumsumNaN在每个切片中的每个列中独立地成为后续值.因此,在我们点击NaN列中的第一个之后,无论我们遇到什么值(NaN或有效数字),结果cumsum仍然是NaN.NaN在我们遇到矩阵列中的第一个负数后,这会有效地传播值.最后一点是在该矩阵中找到那些位置并在原始矩阵中设置相应的位置NaN,从而给出我们的结果.