【问题标题】:Creating a new array that ignores NaN entries创建一个忽略 NaN 条目的新数组
【发布时间】:2021-07-17 16:54:05
【问题描述】:

我有以下数组,其中包含一些 NaN 条目序列:

A = [..., 14, 19, 32, 41, NaN, NaN, NaN, 4, NaN, 51, 62, 74, 58, ...]

在一个循环中,我想遍历数组,当我找到第一个NaN 时,我想构造另一个数组B,其中我使用前面的 4 个值和前 4 个非NaN 值这是在我找到的第一个NaN 之后。所以我的B 应该是这样的:

B = [14, 19, 32, 41, 4, 51, 62, 74, 58]

显然我不能使用B = A(~isnan(A)),因为这只会创建一个A,但没有我不想要的NaN

有没有一种巧妙的方法可以做到这一点?

【问题讨论】:

  • 所以,你基本上描述了一个使用你也提到的函数的循环。你有什么理由不试一试?这里的“整洁”是否意味着“非循环”?请注意,自 ~2007 年以来,没有理由避免 MATLAB 中的循环
  • @AnderBiguri - 我尝试了很多 for 循环,但我无法得到我想要的。 Stackoverflow 对我来说始终是最后的手段。我真的不明白你第一句话的意思。我在for循环中找到第一个NaN,第二个等没有问题让我烦恼的是如何仅提取第一个之后的非NaN。
  • 当然,您尝试过的东西很好。但现在感觉就像一个代码请求,所以用你已经拥有的代码来帮助你比为你编写代码要容易得多。我的第一句话意味着想到的解决方案似乎只是使用你描述的东西,所以你有工具来编写它。您知道如何检测循环中的数字是否为 NaN,然后​​我假设您知道如何从中索引先前的数字,并且您还知道如何索引该数字的后验数字(没有 nan)。你能举个例子吗?

标签: matlab for-loop nan


【解决方案1】:

您可以使用find 获取第一个NaN,并使用它分别从之前和之后的非NaN 元素中获取最后或前4 个元素:

A = [1, 2, 3, 14, 19, 32, 41, NaN, NaN, NaN, 4, NaN, 51, 62, 74, 58, 4, 5, 6];

idxNaN = find( isnan(A), 1 );
idxOK = ~isnan(A);

B = A( [ find(idxOK(1:idxNaN-1), 4, 'last'), idxNaN+find(idxOK(idxNaN+1:end), 4) ] );

B =
    14    19    32    41     4    51    62    74

这里的一件好事是find 将只返回最多 4 个元素(或您请求的任何数量),因此如果之前/之后的可用元素较少,您将不会收到错误NaN。此代码确实假设至少有一个 NaN - 您可以检查 idxNaN 是否为空以使其更加健壮。

【讨论】:

    猜你喜欢
    • 2018-07-10
    • 1970-01-01
    • 2023-02-07
    • 2013-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-21
    • 2021-06-15
    相关资源
    最近更新 更多