MATLAB:如何高效地从矩阵中删除 NaN 元素。

21
我想寻找在MATLAB中高效地(即不使用for循环)从矩阵中移除NaN数字的方法。
以下是一个简单的例子来说明我的目标:
假设我有一个矩阵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))来实现,但这会返回一个向量而不是矩阵。有什么技巧可以让它返回一个矩阵吗?

5个回答

27

如果每行数据要么没有NaN,要么全都是NaN,你可以使用以下方法进行删除:

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

正是我所需要的。谢谢!你知道这是否比Steve建议的reshape命令更快吗? - Berk U.
使用这个方案。这肯定比在删除所有NaN之后再使用reshape更有效率。 - user85109
@jeremiah-willcock @woodchips ... 我们如何为列 M(all(isnan(M), 1), :) = []; 做到这一点,由于某种原因它没有起作用。我转置并使用了这个方法,但应该有更好的方法。谢谢。 - discipulus
1
这将同时删除 inf 值。最好使用 M(~isnan(M(:, 1)), :) - Luis Mendo

20
最好的方法是:
M(any(isnan(M),2),:)=[]

该代码将删除包含至少一个NaN的所有行。


2

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

如果您想忽略(即删除)所有至少包含一个NaN列的行,则只需执行以下操作:

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

2
我建议 M = M(~any(isnan(M), 2), :) - rwong

1

试用我的片段函数。我想用一个简单的函数解决这类典型问题:

B = snip(A,nan)

你可以在此处找到该函数文件。

它还适用于所有其他'x','0'或任何元素,并解决更多类似的问题。


似乎它能够工作,但是并不感觉直观。使用字符串'1'来移除值为1的内容。然而,使用NaN来移除值为NaN的内容。如果要移除字符'1',该怎么办呢?我认为它可以做到的事情可能是合理的,但是请求方式很麻烦。当涉及到更高维度时,也不清楚会发生什么。 - Dennis Jaheruddin

1
以下函数从指定的维度中删除数据中的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是一个字符串?为什么只支持2D数组?为什么不支持N-D数组,并且使用“沿维度”参数来工作,就像sum max和许多其他函数一样? - Shai
1
它可能会起作用,但似乎这个答案既具有高复杂性又缺乏灵活性。至少维度输入应该只是一个数字,这将大大简化您的代码。 - Dennis Jaheruddin
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Shan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接