【问题标题】:MATLAB: How To Efficiently Remove NaN Elements from MatrixMATLAB:如何有效地从矩阵中删除 NaN 元素
【发布时间】:2011-03-05 08:40:22
【问题描述】:

我正在寻找一种方法来有效地从 MATLAB 中的矩阵中删除 NaN 数(即不使用 for 循环)

我将提供一个简单的示例来说明我想要实现的目标:

假设我有一个矩阵 M:

          3.00          1.00
          1.00          3.00
           NaN           NaN
          3.00          3.00
          1.00          1.00
           NaN           NaN
           NaN           NaN
           NaN           NaN
           NaN           NaN
           NaN           NaN

我想找到一种方法将其更改为

          3.00          1.00
          1.00          3.00
          3.00          3.00
          1.00          1.00

我目前正在尝试通过 M(isfinite(M)) 执行此操作,但最终返回的是向量而不是矩阵。有没有技巧让它返回一个矩阵?

【问题讨论】:

    标签: matlab


    【解决方案1】:

    最好的办法是

    M(any(isnan(M),2),:)=[]
    

    这将删除任何包含至少一个 NaN 的行。

    【讨论】:

      【解决方案2】:

      如果每行没有 NaN 或所有 NaN,则可以使用以下方法进行删除:

      M(isfinite(M(:, 1)), :)
      

      【讨论】:

      • 正是我想要的。谢谢!你知道这是否比史蒂夫建议的重塑命令更快?
      • 使用这个方案。这肯定比在删除所有 nans 之后使用 reshape 更有效。
      • @jeremiah-willcock @woodchips ...由于某种原因,我们如何为列M(all(isnan(M), 1), :) = []; 执行此操作不起作用。我转置并使用了它,但应该有更好的方法。谢谢
      • 这也会删除inf 值。更好地使用M(~isnan(M(:, 1)), :)
      【解决方案3】:

      实际上,我想推荐一种稍微不同(并且更通用)的方法。

      因此,如果您想忽略(即删除)至少一列包含NaN 的所有行,那么只需:

      M= M(0== sum(isnan(M), 2), :)
      

      【讨论】:

      • 我建议M = M(~any(isnan(M), 2), :)
      【解决方案4】:

      试试我的 snip function。我想用一个简单的函数来解决这样的典型问题:

      B = snip(A,nan)
      

      你可以找到function file at

      它也适用于所有其他 'x'、'0' 或任何元素,并处理更多类似问题。

      【讨论】:

      • 它似乎有效,但感觉不直观。使用字符串'1' 删除值1。但使用值nan 删除值nan。如果你想删除字符'1',你应该怎么做? ---我认为它可以做的事情可能是合理的,但你必须要求它的方式只是一种痛苦。也不清楚当涉及更高维度时会发生什么。
      【解决方案5】:

      以下函数从指定维度的数据中删除 NAN:

      function data_out = remove_nan (data_in, remove_dim)
      %remove row or col from the data_in if there is a NaN element
      
      % e.g., data_in =[1 2 3 4 NaN; 1 2 3 4 5; 1 2 3 NaN NaN]
      % from this data remove col 4 and 5 such that data_out=[ 1 2 3; 1 2 3; 1 2
      % 3]
      
      if nargin==1
      
          col_loc=any(isnan(data_in),1);
          data_in(:,col_loc)=[];
          data_out=data_in;
      
      elseif nargin==2
      
          if remove_dim=='col'
              %find the cols with nan and remove the colums
              col_loc=any(isnan(data_in),1);
              data_in(:,col_loc)=[];
              data_out=data_in;
          elseif  remove_dim='row'
              %find the rows with nan and remove the rows
              row_loc=any(isnan(data_in),2);
              data_in(row_loc,:)=[];
              data_out=data_in;
          end
      else
          error( 'incorrect no of arguments')
      
      end
      

      【讨论】:

      • 如果你正在为它写一个函数,为什么remove_dim是一个字符串?为什么只支持二维数组?为什么不支持 N-D 数组并使用“沿维度”参数,就像 sum max 和许多其他人一样?
      • 它可能会起作用,但似乎这个答案既有高复杂性又有低灵活性。至少维度输入应该只是一个数字,这也将大大简化您的代码。
      • @DennisJaheruddin 它可以工作,我将它用于 TB 中的巨大数据集,特别是 CSV 文件。我正在寻找针对行或列数据的二维数据集/数据库的函数,但找不到。所以想到了分享。它可以扩展到 N 维。
      猜你喜欢
      • 2014-09-21
      • 2012-02-13
      • 2012-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-02
      相关资源
      最近更新 更多