【问题标题】:How can I get all the index of all the NaNs of a list?如何获取列表的所有 NaN 的所有索引?
【发布时间】:2019-05-17 19:44:47
【问题描述】:

我正在尝试使用列表a 中所有NaNs 的索引创建一个列表。

问题是列表ind 没有填充任何内容。如果不是NaN,而是使用c 之类的随机字符串,它就可以工作。

import numpy as np

a=[1, 2, 3, 4, np.nan, np.nan, 2, np.nan]

ind=[]
for i in range(0,len(a)):

    if a[i]==float("NaN"):
        ind.append(i)
print ind

【问题讨论】:

  • 应该是 np.nan 而不是 a[i]=float("NaN"),但我认为是一样的
  • np.nan 不等于 np.nan,也不等于 float('nan')。使用np.flatnonzero(np.isnan(a))
  • 南家在哪里? np.where(np.isnan(a))[0]

标签: python numpy nan


【解决方案1】:

如果您使用的是 NumPy,您应该真正开始使用数组,并改掉在 Python 级别手动循环的习惯。手动循环通常比让 NumPy 处理事情慢 100 倍左右,而浮点列表占用的内存大约是数组的 4 倍。

在这种情况下,NumPy 可以非常简单地为您提供一个 NaN 索引数组:

ind = numpy.where(numpy.isnan(a))[0]

numpy.isnan 给出一个布尔数组,告诉 a 的哪些元素是 NaN。 numpy.where 给出了一个由 True 元素组成的索引数组,但为了与多维数组的行为一致,包装在一个 1 元素元组中,因此 [0] 从元组中提取数组。

这在a 是一个列表时有效,但你真的应该使用数组。


您的尝试失败,因为 NaN 值彼此不相等或它们本身不相等:

>>> numpy.nan == numpy.nan
False
>>> numpy.nan == float('nan')
False

NaN 以这种方式设计是为了算法方便,使 x != x 在生成 NaN 进行比较的环境中对 NaN 值进行简单检查,并且因为 NaN 具有很少使用的有效负载 在不同的 NaN 之间可能不同的组件。


另一个答案建议进行is numpy.nan 测试,但这是错误且不可靠的。仅当您的 NaN 恰好是特定对象 numpy.nan 时才有效,这种情况很少发生:

>>> float('nan') is numpy.nan
False
>>> numpy.float64(0)/0 is numpy.nan
__main__:1: RuntimeWarning: invalid value encountered in double_scalars
False
>>> numpy.array([numpy.nan])[0] is numpy.nan
False

依靠is numpy.nan 支票,他们会咬你。

【讨论】:

    【解决方案2】:

    使用 np.nan 进行比较

    import numpy as np
    
    a=[1,2,3,4,np.nan,np.nan,2,np.nan]
    
    ind=[]
    for i in range(0,len(a)):
        if a[i] is np.nan:
            ind.append(i)
    print ind
    

    输出

    [4, 5, 7]
    

    使用列表理解:

    [x  for x in range(0,len(a)) if a[x] is np.nan]
    

    或者,如果您使用 numpy 函数构建了数组,则使用 np.isnan(a[i]) 进行比较。

    【讨论】:

    • 这仅适用于您自己构建一个包含单个 np.nan 对象的列表。 Numpy 本身不承诺返回单个 NaN 对象:例如,np.array([np.nan])[0] is np.nan 给我 False,[id(x) for x in np.array([np.nan, np.nan])] 返回两个不同的值。
    • @DSM 你可以使用np.isnan(np.array([np.nan])[0])。感谢您提出这一点。
    猜你喜欢
    • 2016-10-11
    • 2014-08-16
    • 2012-02-22
    • 2015-11-02
    • 2017-06-03
    • 2016-07-22
    • 2019-08-22
    • 2015-03-26
    • 1970-01-01
    相关资源
    最近更新 更多