代码之家  ›  专栏  ›  技术社区  ›  Andi

MATLAB:用NaN替换每列的前导零

  •  1
  • Andi  · 技术社区  · 7 年前

    我有一个3D矩阵叫做 mat

    我确实有一个可行的解决办法。但是,它包含两个for循环。我想知道是否有可能矢量化和摆脱循环。实际上, 垫子

    下面是我的玩具示例:

    % Create test matrix
    mat = randi(100,20,5,2);
    mat(1:5,1,1) = 0;
    mat(1:7,2,1) = 0;
    mat(1:3,4,1) = 0;
    mat(1:10,5,1) = 0;
    mat(1:2,1,2) = 0;
    mat(1:3,3,2) = 0;
    mat(1:7,4,2) = 0;
    mat(1:4,5,2) = 0;
    
    % Find first non-zero element in every column
    [~, firstNonZero] = max( mat ~= 0 );
    
    % Replace leading zeros with NaN
    % How to vectorize this part???
    [nRows, nCols, nPlanes] = size(mat);
    for j = 1 : nPlanes
    
       for i = 1 : nCols
    
           mat(1:firstNonZero(1, i, j)-1, i, j) = NaN;
    
       end
    
    end
    
    1 回复  |  直到 7 年前
        1
  •  6
  •   Wolfie Radu Stefan    7 年前

    你可以用 cumsum 若要创建每列的累计和,则所有前导零的累计和都为零,而所有中间零的累计和都大于零。。。

    mat( cumsum(mat,1) == 0 ) = NaN;
    

    正如评论中所建议的,如果 mat 0

    mat( cumsum(abs(mat),1) == 0 ) = NaN;
    

    请注意,默认情况下, 累加 沿第一个非单例维度操作,可以使用可选的 dim 参数指定维度。我用过 dim=1 高度可以为1,但这是高度大于1的任何矩阵的默认值。

    请注意,它使用 == 作为比较,你可能需要阅读 Why is 24.0000 not equal to 24.0000 in MATLAB? 并使用一个阈值来进行相等比较。